package com.bitoon.basketdudes.ws;

import com.bitoon.basketdudes.jpa.*;
import java.io.PrintWriter;

import java.util.*;
import javax.naming.*;
import javax.persistence.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;


import org.apache.log4j.*;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.output.XMLOutputter;

public class Tienda {

    private static final int ROPA = 1;
    private static final int CARTA = 5;

    Context     initContext = null;
    Context     envContext  = null;
    //DataSource  dsTienda    = null;
    //DataSource  dsCentral   = null;
    Logger log = Logger.getLogger(Tienda.class);

    EntityManagerFactory emfTienda = null;
    //EntityManagerFactory emfBasket = null;
    Configuracion        conf = null;

    public Tienda() {

        try {
            // Conexiones JDBC
            //initContext = new InitialContext();
            //envContext  = (Context)initContext.lookup("java:/comp/env");
            //dsCentral   = (DataSource)envContext.lookup("jdbc/basketdudes_pgpool");

            // JPA Units
            emfTienda = PersistenceManager.getInstance().getEntityManagerFactory("jpa_basket");
            //emfTienda = PersistenceManager.getInstance().getEntityManagerFactory("jpa_catalogo");
            conf = Configuracion.getInstance();
        } catch (Exception e) {
            log.error("[ERROR][constructor]: No se puedo conectar a la base de datos: " , e);
        }

    }

    public void wsComprar (HttpServletRequest request, HttpServletResponse response, boolean p_regalo ) {
        int     equipo_id       = 0;
        int     jugador_id      = 0;
        short   objeto_tipo     = 0;
        int     objeto_id       = 0;
        short   unidades        = 0;
        int     moneda          = 0;
        int     juego_id        = 1;
        int     importe_esperado= -1;
        int     slot            = -1;

        try {

            equipo_id   = Integer.parseInt(request.getParameter("equipo_id"));
            objeto_tipo = Short.parseShort(request.getParameter("objeto_tipo"));
            objeto_id   = Integer.parseInt(request.getParameter("objeto_id"));
            unidades    = Short.parseShort(request.getParameter("unidades"));
            if ( request.getParameter("juego_id") != null)
                juego_id    = Short.parseShort(request.getParameter("juego_id"));

            if ( request.getParameter("moneda") == null ) {
                moneda      = -1;
            }  else {
                moneda      = Integer.parseInt(request.getParameter("moneda"));
log.debug(" Moneda " + moneda);
            }
            if ( request.getParameter("importe") != null)
                importe_esperado = Integer.parseInt(request.getParameter("importe"));
            if ( request.getParameter("jugador_id") != null) {
                jugador_id  = Integer.parseInt(request.getParameter("jugador_id"));
            }            
            if ( request.getParameter("slot") != null)
                slot = Integer.parseInt(request.getParameter("slot"));

            HttpSession miSesion = request.getSession(true);
            String idSesion = miSesion.getId();
            String xml = "";

            if (idSesion != null && equipo_id > 0 && objeto_tipo > 0 &&
                unidades > 0) {

                xml = comprar_moneda( idSesion, equipo_id, objeto_tipo, objeto_id, unidades, 
                        moneda, p_regalo, juego_id, importe_esperado,jugador_id, slot );
             } else {
                log.error("[COMPRAR PARAMETROS] tipo: " + objeto_tipo +
                      " objeto_id " + objeto_id +
                      " equipo "    + equipo_id +
                      " unidades "  + unidades  +
                      " moneda "  + moneda
                      );

                xml = "error=-1;descripcion=incorrect parameters;";
            }


            PrintWriter out = response.getWriter();
            out.print(xml);
        } catch (Exception e) {
            log.error("[ERROR]: Error al escribir en response.getWriter" , e);
        }
    }

    public void wsVender (HttpServletRequest request, HttpServletResponse response) {
        int     equipo_id       = 0;
        short   objeto_tipo     = 0;
        int     objeto_id       = 0;
        short   unidades        = 0;
        int     juego_id        = 1;
        int     importe_esperado=-1;

        try {

            equipo_id   = Integer.parseInt(request.getParameter("equipo_id"));
            objeto_tipo = Short.parseShort(request.getParameter("objeto_tipo"));
            objeto_id   = Integer.parseInt(request.getParameter("objeto_id"));
            unidades    = Short.parseShort(request.getParameter("unidades"));
            if ( request.getParameter("juego_id") != null)
                juego_id    = Short.parseShort(request.getParameter("juego_id"));
            if ( request.getParameter("importe") != null)
                importe_esperado = Integer.parseInt(request.getParameter("importe"));


            HttpSession miSesion = request.getSession(true);
            String idSesion = miSesion.getId();
            String xml = "";

            if (idSesion != null && equipo_id != 0 && objeto_tipo > 0 && unidades > 0
                    //objeto_id >0 &&
                ) {
                xml = vender( idSesion, equipo_id, objeto_tipo, objeto_id, unidades, juego_id, importe_esperado );
            } else {
                log.error("[VENDER PARAMETROS] tipo: " + objeto_tipo +
                      " objeto_id " + objeto_id +
                      " equipo "    + equipo_id +
                      " unidades "  + unidades
                      );

                xml = "error=-1;descripcion=incorrect parameters;";
            }

            PrintWriter out = response.getWriter();
            out.print(xml);
        } catch (Exception e) {
            log.error("[ERROR]: Error al escribir en response.getWriter", e);
        }

    }

    /* Comprar eligiendo la moneda
        p_moneda
             0  - Bitoones
             1  - Dudies

     * 
     * p_regalo= true Regalo Administrativo (no se comprueba sesión, no se retira dinero/puntos a nadie)
     * p_regalo= false Compra normal
     * p_importe_esperado = -1 ( no comprar diferencias de importe)
     * p_importe_esperado > -1 ( comprobar que coincide el importe )
     * p_jugador_id - para la compra de traits se engarza directamente en un jugador

     *
     * Errores:
      -4,  Item not for sale
      -6,  Credito Insuficiente
      -7,  Puntos Insuficientes
      -9,  Nivel Insuficientes
      -10, Unidades por Equipo sobrepasadas
      -11, Fechas de venta sobrepasadas
      -12, Moneda Incorrecta
      -13, Importe Desactualizado
      -14, El equipo no pertenece al usuario
      -22, Maximo unidades por compra sobrepasado
      -29, Equipo no se corresponde a jugador
      -32, Instancia jugador no existe
      -38, Incompatible trait
      -39, Incorrect slot 
      -40, Trait yet equiped       
      * 
     *
     */
    public String comprar_moneda( String p_sesion, int p_equipo_id,
                                  short p_objeto_tipo, int p_objeto_id, short p_unidades,
                                  int   p_moneda, boolean p_regalo, int juego_id,
                                  int   p_importe_esperado, int p_jugador_id,
                                  int   p_slot ) {

        String          retorno         = "";
        StringBuffer    aux_retorno     = new StringBuffer(""); // para las compras que devuelvan más información
        int             aux_usuario_id  = -1;
        Equipo          aux_equipo      = null;
        Jugador         aux_jugador     = null;
        Usuario         aux_usuario     = null;
        int             codError        = -1;
        Item            item            = new Item();
        int             compra_stock    = 0, compra_vendidas = 0;
        java.util.Date  f_actual        = new java.util.Date();
        EntityManager   emt             = null;
        Boolean         comprobar_estado= true;

        item.item_id = p_objeto_id;
        item.unidades_equipo_actuales = p_unidades;
        item.uds_equipo = 0;
        
        // Asignamos la unidades que queremos comprar al item
        item.setUnidades(p_unidades);

        log.debug("[TRAZA][Iniciar Compra] tipo: " + p_objeto_tipo +
                  " objeto_id " + item.item_id + " "+
                  " moneda "    + p_moneda    + " " +
                  " equipo "    + p_equipo_id +
                  " regalo "    + p_regalo    +
                  " unidades "  + item.getUnidades() +
                  " jugador "   + p_jugador_id 
                  );

        if ( p_regalo ) // giveItem
            comprobar_estado = false;
        
        try {
            emt = emfTienda.createEntityManager(); // check 07.08.2012

            if ( p_regalo == false ) {
                LoginAction la = new LoginAction();
                aux_usuario_id = la.comprobarSesionEquipo(p_sesion,p_equipo_id,emt);
                if ( aux_usuario_id < 0 ) {
                    log.error("Sesión Incorrecta "+p_sesion+" "+p_equipo_id+":"+aux_usuario_id);
                    return "error=-3";
                }
            }

            emt.getTransaction().begin();

            aux_equipo  = emt.find(Equipo.class, p_equipo_id);
            if ( aux_equipo == null  ) {
                throw new ExcepcionGeneral( -12, "Team not found" );
            } else {
                // Asignamos el equipo que va a realizar la compra al item
                item.setEquipo(aux_equipo);
            }

            if ( p_jugador_id > 0 ) {
                aux_jugador  = emt.find(Jugador.class, p_jugador_id);
                if ( aux_jugador == null  ) {
                    throw new ExcepcionGeneral( -32, "Player not found" );
                } else {
                    if ( aux_jugador.getEquipo().getId() != aux_equipo.getId() ) {
                        throw new ExcepcionGeneral( -29, "Player's team wrong" );
                    } else {
                        // Asignamos el jugador que va a realizar la compra al item y lo equipará
                        item.setJugador(aux_jugador);
                    }                    
                }                
            }
            
            if ( p_regalo == false && aux_usuario_id != aux_equipo.getUsuario().getId() ) {
                throw new ExcepcionGeneral( -14, "El equipo no pertenece al usuario" );
            }

            if ( p_unidades > 20 ) {
                throw new ExcepcionGeneral( -22, "Maximo unidades por compra sobrepasado" );
            }

            if ( p_unidades!= 1 &&
                 ( p_objeto_tipo ==  1 ||
                   p_objeto_tipo ==  9 ||
                   p_objeto_tipo == 10 ||
                   p_objeto_tipo == 11
                  ) ) {
                throw new ExcepcionGeneral( -24, "Solo una unidad por compra" );
            }


            log.debug("[TRAZA][USUARIO EQUIPO]: " + aux_equipo.getUsuario().getNick() +
                    ", creditos usuario: " + aux_equipo.getUsuario().getCreditos() +
                    ", puntos equipo: " + aux_equipo.getPuntos() );

            switch ( p_objeto_tipo ) {
                case 1: // modelo jugador
                    codError = ComprarMJugador( emt, item );
                break;
                case 2: // ropa
                    codError = ComprarRopa    ( emt, item );
                break;
                case 3: // objeto
                    /* PROVISIONAL, solo se puede comprar un objeto por categoria por ahora,
                     * por lo tanto se venderá previamente el que el usuario  tenga en su almacen
                     * antes de comprar el nuevo.
                     */
                    codError = ComprarObjeto  ( emt, item );
                break;
                case 5: // carta
                    codError = ComprarCarta  ( emt, item );
                    break;
                case 7: // entrenador
                    break;
                case 9:
                    // Los sobres se compran de uno en uno
                    item.setUnidades(1);
                    codError = ComprarSobre ( emt, item, aux_retorno );
                    log.debug("[!!!SOBRE!!!][retorno ]: " + aux_retorno );
                    break;
                case 10:
                    if ( conf.BuscarValorConfiguracionInteger("gashaball") != 0 ) {
                        // Los Gashaball se compran de uno en uno
                        item.setUnidades(1);
                        codError = ComprarGashaball ( emt, item, aux_retorno );
                        log.debug("[!!!GASHABALL!!!][retorno ]: " + aux_retorno );
                        // Si es el gashaball gratuito (-1) o de momento ganador (0) no comprobamos el estado
                        if ( item.item_id < 1 ) {
                            comprobar_estado=false;
                        }
                    }
                    break;
                case 11: // PACKS DE GASHABALL
                    if ( conf.BuscarValorConfiguracionInteger("gashaball") != 0 ) {
                        item.setUnidades(1);
                        codError = ComprarGashaballPack ( emt, item );
                        log.debug("[!!!GASHABALL PACK!!!][retorno ]: " + aux_retorno );
                    }
                    break;
                case 12: // TRAITS
                    item.setUnidades(1);
                    codError = ComprarTrait ( emt, item, p_slot );
                    log.debug("[!!!TRAIT!!!][retorno ]: " + aux_retorno );
                    break;

                default:
                    // ERROR: tipo de objeto no soportado
                    throw new ExcepcionGeneral( -5, "Item type undefined" );

            }

log.debug("[TRAZA][retorno de comprar]: " + codError +"p_moneda"+ p_moneda + " creditos" + item.creditos );

            if ( codError != 0 ) {
                log.error("[TRAZA][ERROR_COMPRAR]: " + retorno );
                throw new ExcepcionGeneral( codError, "Error al comprar" );
            }

            aux_usuario= aux_equipo.getUsuario();
            if ( p_regalo == false ) {
                if ( p_moneda == 0 ) {
                    if (item.creditos > 0) { // El objeto tiene precio, y se compra solo con créditos
                        if ( aux_equipo.getUsuario().getCreditos() < (item.creditos*p_unidades) ) {
                            throw new ExcepcionGeneral( -6, "Credito Insuficiente" + aux_usuario.getId() + " " +
                                    item.creditos + " usuario (" + aux_usuario.getCreditos()+") ("+  item.creditos*p_unidades+")"  );
                        }
                        if ( p_importe_esperado> -1 && p_importe_esperado != item.creditos ) {
                            throw new ExcepcionGeneral( -13, "Importe desactualizado" + aux_usuario.getId() + " " + p_importe_esperado + " " + item.creditos   );
                        }
                    }
                } else { // Se compra con puntos
                    if ( aux_equipo.getPuntos() < new Integer(item.puntos*p_unidades) ) {
                        throw new ExcepcionGeneral( -7, "Puntos Insuficientes: (" + aux_equipo.getPuntos() + ") (" + item.puntos*p_unidades + ")" );
                    }
                    if ( p_importe_esperado> -1 && p_importe_esperado != item.puntos ) {
                            throw new ExcepcionGeneral( -13, "Importe desactualizado" + aux_usuario.getId() + " " + p_importe_esperado + " " + item.puntos   );
                    }
                }
            }
            if ( p_regalo == false && // 16-12-2011 giveitem puede dar objetos de cualquier nivel
                 item.nivel!= 0 && item.nivel> aux_equipo.getNivel()  ) {
                throw new ExcepcionGeneral( -9, "Nivel Insuficientes" + aux_equipo.getNivel() + " " + item.nivel );
            }

            // Si no es una articulo activo (1) o de venta solo en tienda (3) lo rechazamos
            if ( comprobar_estado && item.estado!= 1 && item.estado!= 3) {
                log.error("Item not for sale" + item.item_id + " equipo " + p_equipo_id+ " estado " + item.estado );
                throw new ExcepcionGeneral( -4, "Item not for sale" );
            }


            if ( item.uds_equipo!= -1  && item.unidades_equipo_actuales > item.uds_equipo) {
                throw new ExcepcionGeneral( -10, "Unidades por Equipo sobrepasadas " + item.uds_equipo+ " compradas" + item.unidades_equipo_actuales );
            }

            if ( (item.f_ini != null && item.f_ini.compareTo(f_actual)>0)  ||
                 (item.f_fin != null && f_actual.compareTo(item.f_fin) >0)  ) {
                throw new ExcepcionGeneral( -11, "Fechas de venta sobrepasadas " + item.f_ini + " " + item.f_fin );
            }

            if ( p_regalo || item.creditos >0 || item.puntos >0  ) { 
                // No guardamos movimientos de objetos que cuesten 0 duddie y bitoons)
                // Si guardamos los regalos (giveitem)

                // Inserto un nuevo movimiento
                Movimiento movimiento = new Movimiento();
                movimiento.setUsuarioId (aux_equipo.getUsuario().getId());
                movimiento.setJuegoId (juego_id);
                switch ( movimiento.getJuegoId())
                {
                    case 1:
                        {
                            movimiento.setEquipoId  (aux_equipo.getId());
                            movimiento.setNivel     (aux_equipo.getNivel());

                            EstEquipo est_equipo  = emt.find(EstEquipo.class, p_equipo_id);
                            if ( est_equipo == null  ) {
                                movimiento.setPartidos(0);
                            } else {
                                movimiento.setPartidos(est_equipo.getPartidos());
                            }
                        }
                        break;
                    default:
                        movimiento.setEquipoId(0);
                        movimiento.setNivel(0);
                        movimiento.setPartidos(0);
                        break;
                }

                if ( p_regalo == true) {
                    movimiento.setTipo  ((short)4);
                } else {
                    movimiento.setTipo  ((short)1);
                }
                movimiento.setFAlta (f_actual);

                movimiento.setValor(0);
                movimiento.setPuntos(0);

//                if ( p_regalo == false || (item.puntos!=0 || item.creditos!=0) ) {
//              08/06/2012 Solo asignamos importe cuando no sea un regalo
//              Error reportado por Taiwan al hacer giveItem error -12 Moneda Incorrecta
                if ( p_regalo == false ) {

                    if ( item.creditos!=0 || item.puntos!=0 ) {


                        if (item.creditos > 0 && p_moneda== 0) {
    log.debug("Comprar por bitoones " + item.creditos );
                            movimiento.setValor ( p_unidades * item.creditos );
                        } else {
                            if (item.puntos > 0 && p_moneda== 1) {
    log.debug("Comprar por dudies" + item.puntos );
                                movimiento.setPuntos( (p_unidades * item.puntos));
                            } else {
                                throw new ExcepcionGeneral( -12, "Moneda Incorrecta " + item.puntos + " " + item.creditos + " " + p_moneda );
                            }
                        }
                    } else {
    log.debug("Comprar gratis" );
                    }
                }

                /* Guardamos el saldo resultante de la operacion */
                movimiento.setSaldoDinero(aux_usuario.getCreditos() - movimiento.getValor());
                movimiento.setSaldoPuntos(aux_equipo.getPuntos()    - movimiento.getPuntos());
                movimiento.setItemTipo   (p_objeto_tipo);
                movimiento.setItemId     (p_objeto_id);
                movimiento.setItemUds    (p_unidades);
                movimiento.setConcepto   (item.getConcepto());
                if ( p_equipo_id >0)
                    movimiento.setEquipoId  (p_equipo_id);

                emt.persist( movimiento);

                log.debug("[TRAZA][MOVIMIENTO GUARDADO]: "
                    + " $:"  + movimiento.getValor()
                    + " pt:" + movimiento.getPuntos()
                    + " ud:" + movimiento.getItemUds());

                /* Actualizo el crédito y los puntos del usuario */
                log.debug("[TRAZA][creditos antes]: " +  aux_usuario.getCreditos()  + " " + movimiento.getValor() );
                log.debug("[TRAZA][puntos antes]: "   +  aux_equipo.getPuntos()    + " " + movimiento.getPuntos() );

                // Si el objeto tiene precio, quitar sólo creditos
                if ( p_regalo == false ) {
                    if (movimiento.getValor() > 0) {
                        aux_usuario.setCreditos( aux_usuario.getCreditos() - movimiento.getValor());
                    } else {
                        aux_equipo.setPuntos( (int)aux_equipo.getPuntos() - (int)movimiento.getPuntos());
                    }
                }
                log.debug("[TRAZA][creditos]: " +  aux_usuario.getCreditos()  + " " + movimiento.getValor() );
                log.debug("[TRAZA][puntos]: "   +  aux_equipo.getPuntos()    + " " + movimiento.getPuntos() );
            }

            emt.getTransaction().commit();

            // Comprobamos si la compra ha producido INSTANCIAS UNICAS:
            // OJO SOLO FUNCIONA CON GASHABALLS DE UNA UNIDAD
            // O CON COMPRAS DE ROPA DE MULTIPLES UNIDADES DE LA MISMA ROPA.
            if ( item.getListaInstancia().size()>0) {

                Boolean     primero=true;
                String      aux_instancia="";
                Iterator    iter = item.getListaInstancia().iterator();
                while (iter.hasNext()) {
                    RopaInstancia instancia = (RopaInstancia)iter.next();
                    log.debug("[TRAZA][COMPRA CON INSTANCIAS]" );
                    if (primero) {
                        primero=false;
                        aux_instancia="caduca="+Util.FechaFormateada(instancia.getFCaduca())+";id={";
                    } else {
                        aux_instancia+=",";
                    }
                    aux_instancia+=instancia.getId();
                }
                aux_instancia+="};";
                aux_retorno.ensureCapacity(aux_instancia.length());
                aux_retorno.append(aux_instancia);
            }

            log.debug("[TRAZA][COMMIT]" );
            retorno = "error=0;descripcion=Item purchased;credito=" + aux_usuario.getCreditos() + ";puntos=" + aux_equipo.getPuntos()+ ";"+aux_retorno;

        } catch (ExcepcionGeneral ex) {
            log.error("[ERROR][comprar]: " , ex);
            retorno = "error="+ex.getCodigo()+";descripcion="+ex.getDescripion()+ ";";
            if ( emt != null && emt.getTransaction().isActive() )
                emt.getTransaction().rollback();
        } finally {
            try { if (emt != null) emt.close(); } // revisado 09/08/2012
            catch (Exception e) {
                log.error("[ERROR][constructor]: EMT base de datos: " , e);
            }
        }

        return retorno;
    }

//    private int ComprarMJugador( EntityManager emt, Item item, Equipo p_equipo, short p_unidades ) throws ExcepcionGeneral {
    private int ComprarMJugador( EntityManager emt, Item item ) throws ExcepcionGeneral {

//        int retorno = GuardarMJugadorInventario( emt, item, p_equipo, p_unidades );
        int retorno = GuardarMJugadorInventario( emt, item );
        if ( retorno != 0)
            return retorno;
        if ( item.stock != -1 ) {
            if ( item.stock-item.vendidas < item.getUnidades() ) {
                log.error("[ERROR][Stock Insuficiente]: " );
                throw new ExcepcionGeneral( -20, "Stock exhausted" );
                //return -20; /* stock insuficiente */
            }
        }

        return 0;
    }

//    int GuardarMJugadorInventario ( EntityManager emt, Item item, Equipo p_equipo, short p_unidades ) throws ExcepcionGeneral {
    int GuardarMJugadorInventario ( EntityManager emt, Item item ) throws ExcepcionGeneral {

        MJugador objeto = emt.find(MJugador.class, item.item_id);
        if ( objeto == null)
            throw new ExcepcionGeneral( -19, "Item identifier not found" );
            //return -3;


        item.asignarValores( //p_equipo.getId(), p_unidades,
                             objeto.getPrecio(),objeto.getPuntos(),
                             objeto.getStockTotal(),objeto.getVendidas(),
                             objeto.getNivel(),objeto.getUdsEquipo(),
                             objeto.getFIni(),objeto.getFFin(),
                             objeto.getEstado(), 0
                             );

        /* Comprobamos si sobrepasa máx uds equipo */
        Plantilla equipo_objeto=null;
        Plantilla nuevo = new Plantilla();

        /* Comprobamos cuantos modelos iguales tiene el equipo */
        Query q = emt.createNativeQuery("SELECT * FROM basket.Jugador where  equipo_id=:equipoId and m_jugador_id = :mJugadorId");

        q.setParameter("equipoId"    , item.getEquipo().getId());
        q.setParameter("mJugadorId"  , item.item_id);

        List<Jugador> lista = q.getResultList();

        if ( !lista.isEmpty() ) {
            item.unidades_equipo_actuales += 1;
            log.error("[ERROR][MODELO de jugador ya existe en equipo]: "+item.getEquipo().getId()+" "+item.item_id );
            throw new ExcepcionGeneral( -16, "Duplicated player" );
            //return -16;
        }

        /* Comprobamos cuantos jugadores tiene el equipo el máximo es 15*/
        int result = ((java.math.BigInteger)emt.createNativeQuery("SELECT count(jugador_id) as cuantos FROM basket.plantilla where equipo_id= "
                +item.getEquipo().getId()).getSingleResult()).intValue();
        if (result >=15) {
            throw new ExcepcionGeneral( -15, "Max players per team" );
            // return -15; // maximo jugadores por equipo
        }

        /* Creamos el jugador individual con el modelo como plantilla */
        Jugador jugador = new Jugador();
        jugador.setMJugador     (objeto);
        jugador.setPrecioCompra (objeto.getPrecio());
        jugador.setPuntosCompra (objeto.getPuntos());

        /* Asignamos las modificadas por la ropa a 0 */
        jugador.ResetRopa();

        /* Asignamos las basicas */
        jugador.setBT1           (objeto.getT1());
        jugador.setBT2           (objeto.getT2());
        jugador.setBT3           (objeto.getT3());
        jugador.setBAgresividad  (objeto.getAgresividad());
        jugador.setBDriblin      (objeto.getDriblin());
        jugador.setBPase         (objeto.getPase());
        jugador.setBReboteAtaque (objeto.getReboteAtaque());
        jugador.setBReboteDefensa(objeto.getReboteDefensa());
        jugador.setBDefensa      (objeto.getDefensa());
        jugador.setBRobo         (objeto.getRobo());
        jugador.setBTapon        (objeto.getTapon());
        jugador.setBResistencia  (objeto.getResistencia());
        jugador.setBVelocidad    (objeto.getVelocidad());
        jugador.setBSprint       (objeto.getSprint());
        jugador.setBTeamwork     (objeto.getTeamwork());
        jugador.setNivel         ((short)objeto.getNivelIni());
        
        if ( objeto.getTrait() != null) {
            jugador.setTrait1(objeto.getTrait().getId());
        }
        
        /* El jugador parte con la experiencia base de su nivel */
        DatosEquipo datos_equipo = new DatosEquipo();
        jugador.setExperiencia(datos_equipo.experienciaBaseNivel( objeto.getNivelIni()-1 ) + 1);
log.debug(" nivel " + objeto.getNivelIni() + " experiencia " + jugador.getExperiencia() );

        jugador.recalculaValoracion( );

//        Equipo equipo = new Equipo();
//        equipo.setId(p_equipo_id);
        jugador.setEquipo(item.getEquipo());

        emt.persist(jugador);

        item.setConcepto( "serial: " + jugador.getId() );
        
        Vestidor vestidor = new Vestidor();
        vestidor.calcularPowerPlay(emt, item.getEquipo());

        /* Metemos al jugador en la plantilla */
        PlantillaPK pk = new PlantillaPK ( );
        pk.setEquipoId(item.getEquipo().getId());

        pk.setJugadorId(jugador.getId());
        nuevo.setPlantillaPK ( pk );

        /* buscar dorsal libre */
        nuevo.getPlantillaPK().setDorsal( dorsalLibre( emt, item.getEquipo().getId()) );
        nuevo.setDemarcacion( (short)ultimaDemarcacion(emt, item.getEquipo().getId()) );

        /* todo jugador comprado no es titular */
        nuevo.setTitular((short)0);

        /* Añadimos el mjugador a la plantilla */
        emt.persist(nuevo);

        /* decrementar stock */
        if ( objeto.getStockTotal() != -1) {
log.debug(" OBJETO DE STOCK LIMITADO");
            objeto.setVendidas(item.vendidas + item.getUnidades() );
        }


        return 0;
    }

//    private int ComprarObjeto( EntityManager emt, Item item, int p_equipo_id, short p_unidades ) throws ExcepcionGeneral {
    private int ComprarObjeto( EntityManager emt, Item item ) throws ExcepcionGeneral {
//        int retorno = GuardarObjetoInventario( emt, item, p_equipo_id, p_unidades );
        int retorno = GuardarObjetoInventario( emt, item );
        if ( retorno != 0)
            return retorno;

        if ( item.stock != -1 ) {
            if ( item.stock-item.vendidas < item.getUnidades() ) {
                log.error("[ERROR][Stock Insuficiente]: " );
                throw new ExcepcionGeneral( -20, "Stock exhausted" );
                //return -20; /* stock insuficiente */
            }
        }

        return 0;
    }


//    int GuardarObjetoInventario( EntityManager emt, Item item, int p_equipo_id, short p_unidades ) throws ExcepcionGeneral {
    int GuardarObjetoInventario( EntityManager emt, Item item ) throws ExcepcionGeneral {
log.debug("[TRAZA][COMPRAR OBJETO]: " + item.getEquipo().getId() + " " + item.item_id + item.getUnidades() );

        Objeto objeto = emt.find(Objeto.class, item.item_id);
        if ( objeto == null) 
            throw new ExcepcionGeneral( -19, "Item identifier not found" );
            //return -3;
            
        item.asignarValores( //p_equipo_id, p_unidades,
                             objeto.getPrecio(),objeto.getPuntos(),
                             objeto.getStockTotal(),objeto.getVendidas(),
                             objeto.getNivel(),objeto.getUdsEquipo(),
                             objeto.getFIni(),objeto.getFFin(),
                             objeto.getEstado(), 0
                             );

        /* Comprobamos si el equipo tiene un objeto de dicha categoria en el almacen
         * en cuyo caso hacemos una venta. Este funcionamiento algún día podrá cambiar
         * y permitirá tener en el almacen varios objetos de la misma categoría.
         * Si la categoria es 0 no se realiza esta comprobación
         */
        if ( objeto.getCategoria().getId() != 0 ) {
            Query q = emt.createNamedQuery("EquipoObjeto.findByEquipoIdCategoriaId");
            q.setParameter("equipoId"    , item.getEquipo().getId());
            q.setParameter("categoriaId" ,objeto.getCategoria().getId());

            List<EquipoObjeto> lista = q.getResultList();
            if ( !lista.isEmpty() ) {
                if ( objeto != null) {
                    return -10;
                }
            }
        }

        /* Comprobamos si sobrepasa máx uds equipo */
        EquipoObjeto equipo_objeto=null;
        EquipoObjeto nuevo = new EquipoObjeto();

        Query q = emt.createNamedQuery("EquipoObjeto.findByEquipoIdObjetoId");
        q.setParameter("equipoId"   , item.getEquipo().getId());
        q.setParameter("objetoId"   ,item.item_id);

        List<EquipoObjeto> lista = q.getResultList();

        if ( !lista.isEmpty() ) {
            /* Actualizamos el numero de objetos del almacen del equipo */
            equipo_objeto = lista.get(0);

/*          item.unidades_equipo_actuales += equipo_objeto.getCantidad();
            equipo_objeto.setCantidad( item.unidades_equipo_actuales );    */

            equipo_objeto.setCantidad( (short) (equipo_objeto.getCantidad() + item.getUnidades()) );
            item.unidades_equipo_actuales = equipo_objeto.getCantidad();
        } else {
            /* Añadimos el objeto al almacen del equipo */
            EquipoObjetoPK pk = new EquipoObjetoPK ( );
            pk.setEquipoId(item.getEquipo().getId());
            pk.setObjetoId(item.item_id);

            nuevo.setEquipoObjetoPK ( pk );
            nuevo.setCantidad( (short)item.getUnidades() );

            emt.persist(nuevo);
        }

        /* decrementar stock */
        if ( objeto.getStockTotal() != -1) {
log.debug(" OBJETO DE STOCK LIMITADO");
            objeto.setVendidas(item.vendidas + item.getUnidades());
        }
        return 0;
    }



//    private int ComprarSobre( EntityManager emt, Item p_item, int p_equipo_id, short p_unidades, StringBuffer p_contenido_sobre ) throws ExcepcionGeneral {
    private int ComprarSobre( EntityManager emt, Item p_item, StringBuffer p_contenido_sobre ) throws ExcepcionGeneral {
        String  aux_sobre       ="";
        int     carta_azar_id   =0;
        Item    item            = new Item();

log.debug("[TRAZA][COMPRAR SOBRE]: " + p_item.item_id );

        Sobre objeto = emt.find(Sobre.class, (short)p_item.item_id);
        if ( objeto == null)
            throw new ExcepcionGeneral( -19, "Item identifier not found" );
            //return -3;


        p_item.asignarValores(  //p_equipo_id, p_unidades,
                                objeto.getPrecio(),objeto.getPuntos(),
                                objeto.getStockTotal(),objeto.getVendidas(),
                                objeto.getNivel(),(short)-1,
                                objeto.getFIni(),objeto.getFFin(),
                                objeto.getEstado(), 0
                             );

        try {
log.debug("[TRAZA][Categoría Sobre]: " + objeto.getCategoriaId() );
            for (int i=1;i<7;i++) {

                int nivel = AzarNivel( item, objeto.getCategoriaId() );

                if ( i < 4) {
                    carta_azar_id = AzarCarta (emt, 1, nivel); // Comun
                    log.debug("[Rareza Comun]: " + carta_azar_id + " nivel " + nivel );
                } else if ( i < 6) {
                    carta_azar_id = AzarCarta (emt, 2, nivel); // Infrecuente
                    log.debug("[Rareza Infrecuente]: " + carta_azar_id + " nivel " + nivel );
                } else if ( i < 7) {
                    carta_azar_id = AzarCarta (emt, 3, nivel); // Rara
                    log.debug("[Rareza Rara]: " + carta_azar_id + " nivel " + nivel );
                } else {
                    throw new ExcepcionGeneral( -21, "Rarera imposible" + carta_azar_id);
                }

                Item item_carta = new Item();
                item_carta.item_id = carta_azar_id;
                item_carta.unidades_equipo_actuales=1;
                item_carta.setUnidades(1);
                item_carta.setEquipo(p_item.getEquipo());

//                int ret = ComprarCarta ( emt,item_carta,(short)1 );
                int ret = GuardarCartaInventario ( emt, item_carta );
                if ( ret != 0 )
                    return ret;
                aux_sobre += "carta"+String.valueOf(i)+"=" + String.valueOf(carta_azar_id)+";" ;

            }

log.debug("[TRAZA][COMPRAR SOBRE]: Precio creditos" + p_item.creditos + " precio puntos " + p_item.puntos + " estado " + p_item.estado );
        } catch (ExcepcionGeneral ex) {
            log.error("[ERROR][comprar]: " , ex);
            aux_sobre += "error="+ex.getCodigo()+";descripcion="+ex.getDescripion()+ ";";
        } catch (Exception e) {
            log.error("[ERROR][comprar]: " , e);
        } finally {
            p_contenido_sobre.ensureCapacity(aux_sobre.length());
            p_contenido_sobre.append(aux_sobre);

            log.debug("<<<<<<<<<<<<<<<CONTENIDO>>>>>>>>>>>>>>>>>>>>" +p_contenido_sobre);
            return 0;
        }
        
    }

    private int ComprarGashaball( EntityManager emt, Item p_item, StringBuffer p_contenido_sobre ) throws ExcepcionGeneral {
        String      aux_sobre       ="";
        int         carta_azar_id   =0;
        int         rareza_tirada   =0;
        int         codError        =0;
        int         objeto_id       =-1;
        int         retorno         =-1;
        int         suma_prob       =0;
        Item        item_aux        =new Item();
        short       quedan          =-1; // credito restante de equipo_gashaball (-1 para compras individuales)

log.debug("[TRAZA][COMPRAR GASHABALL]: " + p_item.item_id );
        try {
            Gashaball objeto = emt.find(Gashaball.class, (short)p_item.item_id);
            if ( objeto == null)
                throw new ExcepcionGeneral( -19, "[Gashaball] Item identifier not found" );

            p_item.asignarValores(  //p_equipo.getId(), p_unidades,
                                    objeto.getPrecio(),objeto.getPuntos(),
                                    objeto.getStockTotal(),objeto.getVendidas(),
                                    objeto.getNivel(),(short)-1, // No hay límite en los gashaballs
                                    objeto.getFIni(),objeto.getFFin(),
                                    objeto.getEstado(),0
                                 );
            if ( objeto.getNumItems() < 1 ) {
                throw new ExcepcionGeneral( retorno, "[Gashaball] numero incorrecto items" );
            }

            // Comprobamos si el usuario tiene credito por compra de packs de gashaballs
            // y lo gastamos en lugar de cobrarle puntos o dinero
            EquipoGashaball equipo_gashaball=buscaEquipoGashaball ( emt,
                                    p_item.getEquipo().getId(), (short)p_item.item_id );
            if (equipo_gashaball != null ) {
                p_item.creditos=0;
                p_item.puntos  =0;
log.debug("Compra con creditos " + p_item.item_id + " quedan " + equipo_gashaball.getCantidad());
                equipo_gashaball.setCantidad( equipo_gashaball.getCantidad() -1);
                if ( equipo_gashaball.getCantidad() <= 0 ) {
                    emt.remove( equipo_gashaball );
                }
                quedan = (short)equipo_gashaball.getCantidad();
            }

            // Si es un gashaball diario gratuito (ID -1) no se cobra y lo marcamos como utilizado
            Bonus bonus= new Bonus();
            if ( p_item.item_id == -1 ) {
                int bonus_dia = bonus.consultarGashaballDiario ( emt, p_item.getEquipo().getId() );
                if ( bonus_dia < 0 )
                    throw new ExcepcionGeneral( retorno, "[Gashaball] Gratuito diario consumido " + bonus_dia );
                p_item.creditos=0;
                p_item.puntos  =0;

                regalaDuddies(emt, p_item.getEquipo().getId(), bonus_dia);

                aux_sobre += "bonus="+bonus_dia+";" ;
log.debug("Bonus " + bonus_dia );
            }
            // COMPROBAMOS SI TOCA MOMENTO GANADOR SE TOMAN LOS ITEMS DEL GASHABALL 0
            if ( bonus.MomentoGanador (emt, p_item.getEquipo() ) ) {
log.debug("Momento Ganador " + new Date().toString() );
                objeto = emt.find(Gashaball.class, (short)0 );
                if ( objeto == null)
                    throw new ExcepcionGeneral( -19, "[Gashaball] No existe Gashaball de Momento Ganador!!!!!!!!!!!!!!!!!!!!!!" );
            }

            Query q = emt.createNamedQuery("Gashaballitem.findByParent");
            q.setParameter("padre"   ,(short)objeto.getId() );

            List<Gashaballitem> lista = q.getResultList();
            if ( lista.isEmpty() ) {
                throw new ExcepcionGeneral( retorno, "[Gashaball] no hay items" );
            }

            // Sumamos las probabilidades de los items que puede entregar este gashaball
            for ( int x=0; x< lista.size() ; x++) {
                suma_prob += lista.get(x).getProbability();
            }

            for ( int i=0; i< objeto.getNumItems() ; i ++) {
log.debug("[TRAZA][GASHABALL] Total prob: " + suma_prob );
                // y hacemos una tirada entre 1 la suma acumulada de la probabilidad
                int parcial = 0;
                int indice  = 0;
                int tipo    = 2;
                int tirada  = (int)(Math.random()*suma_prob)+1;

                // Tomamos el tipo de objeto del item elegido
                for ( indice=0; indice< lista.size() ; indice++) {
                    parcial += lista.get(indice).getProbability();
                    if ( parcial >= tirada) {
                        tipo  = lista.get(indice).getItemType();
                        objeto_id = lista.get(indice).getItemId  ();
                        indice= lista.size(); // salimos del bucle
                    }
                }
log.debug("[TRAZA][GASHABALL] Datos: a " + parcial + " "  + suma_prob + " " + tirada );
                if ( objeto_id == -1)
                    throw new ExcepcionGeneral( retorno, "[Gashaball] probabilidad erronea " + parcial + " "  + suma_prob + " " + tirada );

                switch ( tipo ) {

                    case 1: // modelo jugador
                        item_aux.item_id= objeto_id;
                        item_aux.setUnidades(1);
                        item_aux.setEquipo(p_item.getEquipo());

                        try {
                            retorno = GuardarMJugadorInventario( emt, item_aux );

                            if ( retorno != 0)
                                throw new ExcepcionGeneral( retorno, "Error al Guardar Jugador" );
                            aux_sobre += "jug"+String.valueOf(i)+"=" + String.valueOf(objeto_id)+";" ;
                        } catch (ExcepcionGeneral e) {
                            // si no puede recibir al jugador en la plantilla por tener 15 jugadores
                            // o por tener ya al jugador, le damos 50.000 duddies
                            regalaDuddies(emt, p_item.getEquipo().getId(), 50000);

                            aux_sobre += "dud"+String.valueOf(i)+"=50000;" ;
                            tipo      = 100;
                            objeto_id = 50000;
                        }
                        break;
                    case 2: // ropa
                        item_aux.item_id= objeto_id;
                        item_aux.setUnidades(1);
                        item_aux.setEquipo(p_item.getEquipo());
                        retorno=GuardarRopaInventario ( emt, item_aux );
                        if ( retorno != 0)
                            throw new ExcepcionGeneral( retorno, "[Gashaball] Error al Guardar Ropa " );
                        aux_sobre += "ropa"+String.valueOf(i)+"=" + String.valueOf(objeto_id)+";" ;

                        if ( item_aux.getListaInstancia().size()>0 )
                            p_item.addInstancia(item_aux.getListaInstancia().get(0));

                        // AVISO EL GASHABALL SOLO PUEDE DEVOLVER UNA UNIDAD
                        // PARA QUE PUEDA DEVOLVER VARIAS UNIDADES HAY QUE MODIFICAR EL RETORNO DE LA FUNCION

                    break;
                    case 5: // carta
                        item_aux.item_id= objeto_id;
                        item_aux.setUnidades(1);
                        item_aux.setEquipo(p_item.getEquipo());
                        GuardarCartaInventario ( emt, item_aux );
                        if ( retorno != 0)
                            throw new ExcepcionGeneral( retorno, "[Gashaball] Error al Guardar Carta Inventario" );
                        aux_sobre += "carta"+String.valueOf(i)+"=" + String.valueOf(objeto_id)+";" ;
                        break;
                    case 100: // duddies
                            regalaDuddies(emt, p_item.getEquipo().getId(), objeto_id);

                            aux_sobre += "dud"+String.valueOf(i)+"="+objeto_id+";" ;
                        break;

                    default:
                            throw new ExcepcionGeneral( retorno, "[Gashaball] Tipo de objeto erroneo" );

                }
                GashaballMovimiento gm = new GashaballMovimiento ();
                gm.setEquipo( p_item.getEquipo() );
                gm.setFecha(new Date());
                gm.setGashaball(objeto);
                gm.setTipo((short)tipo);
                gm.setItemId(objeto_id);
                gm.setQuedan(quedan);
                emt.persist(gm);
            }

log.debug("[TRAZA][COMPRAR GASHABALL]: Precio creditos" + p_item.creditos + " precio puntos " + p_item.puntos + " estado " + p_item.estado);
        } catch (ExcepcionGeneral ex) {
            log.debug("error comprar gashaball",ex);
            aux_sobre += "error="+ex.getCodigo()+";descripcion="+ex.getDescripion()+ ";";
        } catch (Exception e) {
            log.error("[ERROR][comprar]: " , e);
        } finally {
            p_contenido_sobre.ensureCapacity(aux_sobre.length());
            p_contenido_sobre.append(aux_sobre);

            log.debug("<<<<<<<<<<<<<<<CONTENIDO>>>>>>>>>>>>>>>>>>>>" +p_contenido_sobre);
            return 0;
        }
    }

    private int ComprarGashaballPack( EntityManager emt, Item p_item ) throws ExcepcionGeneral {
        int         retorno         =-1;
        EquipoGashaball             equipo_gashaball=null;

log.debug("[TRAZA][COMPRAR GASHABALL PACK]: " + p_item.item_id );
        try {
            GashaballPack objeto = emt.find(GashaballPack.class, (short)p_item.item_id);
            if ( objeto == null) {
                throw new ExcepcionGeneral( -19, "[GashaballPack] Item identifier not found" );
            }

            p_item.asignarValores(  //p_equipo.getId(), p_unidades,
                                    objeto.getPrecio(),objeto.getPuntos(),
                                    objeto.getStockTotal(),objeto.getVendidas(),
                                    objeto.getNivel(),(short)-1, // No hay límite en los gashaballs
                                    objeto.getFIni(),objeto.getFFin(),
                                    objeto.getEstado(),0
                                 );

log.debug("[TRAZA] precio " + objeto.getPrecio() + " puntos " + objeto.getPuntos() + " cantidad " + objeto.getCantidad() );

            // Buscamos equipo_gashaball para incrementar el credito
            equipo_gashaball=buscaEquipoGashaball ( emt,
                            p_item.getEquipo().getId(),
                            (short)objeto.getGashaball().getId() );

            if ( equipo_gashaball== null ) {
                // Si no existe lo creamos
                EquipoGashaballPK clave = new EquipoGashaballPK ();
                clave.setEquipoId(p_item.getEquipo().getId());
                clave.setGashaballId(objeto.getGashaball().getId());

                equipo_gashaball = new EquipoGashaball ();
                equipo_gashaball.setEquipoGashaballPK(clave);
                equipo_gashaball.setCantidad(0);
                emt.persist(equipo_gashaball);
            } 

log.debug (" CANTIDAD:" + objeto.getCantidad() );
            equipo_gashaball.setCantidad( equipo_gashaball.getCantidad() + objeto.getCantidad() );


log.debug("[TRAZA][COMPRAR GASHABALL PACK]: Precio creditos" + p_item.creditos + " precio puntos " + p_item.puntos + " estado " + p_item.estado);
        } catch (ExcepcionGeneral ex) {
            log.error("[ERROR][comprar]: " , ex);
        } catch (Exception e) {
            log.error("[ERROR][comprar]: " , e);
        } finally {
            return 0;
        }
    }

    
    int ComprarTrait ( EntityManager emt, Item item, int p_slot ) throws ExcepcionGeneral {
log.debug("[TRAZA][COMPRAR TRAIT]: " + item.getEquipo().getId() + " " + item.item_id + item.getUnidades() );
        int trait_anterior=0;
        
        if ( item.getJugador() == null) {
            throw new ExcepcionGeneral( -32, "Player not found" );
        }

        Trait objeto = emt.find(Trait.class, (short)item.item_id);
        if ( objeto == null) 
            throw new ExcepcionGeneral( -19, "Item identifier not found" );
            //return -3;
            
        item.asignarValores( //p_equipo_id, p_unidades,
                             objeto.getPrecio().floatValue(),objeto.getPuntos(),
                             objeto.getStockTotal(),objeto.getVendidas(),
                             objeto.getNivel(),objeto.getUdsEquipo(),
                             objeto.getFIni(),objeto.getFFin(),
                             objeto.getEstado(), 0
                             );

        // Comprobamos si m_jugador admite el trait

      
        Query q = emt.createNamedQuery("MJugadorTrait.findByMJugador");
        q.setParameter("trait_id"    , (short)item.item_id );
        q.setParameter("m_jugador_id" ,item.getJugador().getMJugador().getId().shortValue());

        List<MJugadorTrait> lista = q.getResultList();
        if ( lista.isEmpty() ) {
            throw new ExcepcionGeneral( -38, "Incompatible trait m_jugador" );
        } else {
            Integer auxi = item.item_id;
            Short   trait_id = auxi.shortValue();

            // Si el trait ya lo tiene equipado no permitimos que malgaste el dinero
            if ( (item.getJugador().getTrait1()!= null && item.getJugador().getTrait1().shortValue()== trait_id.shortValue() ) ||
                 (item.getJugador().getTrait2()!= null && item.getJugador().getTrait2().shortValue()== trait_id.shortValue() )
                ) {
                throw new ExcepcionGeneral( -40, "Trait yet equiped" );                
            }
            
            // Asignamos el trait al jugador            
            if ( p_slot == 1 ) {
                if ( item.getJugador().getTrait1()!= null ) {
                    trait_anterior=item.getJugador().getTrait1();
                }
                item.getJugador().setTrait1( trait_id );
            } else if ( p_slot == 2 ) {
                if ( item.getJugador().getTrait1()!= null ) {
                    trait_anterior=item.getJugador().getTrait2();
                }
                item.getJugador().setTrait2( trait_id );
            } else {
                throw new ExcepcionGeneral( -39, "Incorrect slot" );                
            }
        }

        /* decrementar stock */
        if ( objeto.getStockTotal() != -1) {
log.debug(" OBJETO DE STOCK LIMITADO");
            objeto.setVendidas(item.vendidas + item.getUnidades());
            // Guardamos el identificador del jugador y el trait anterior
            // para aumentar la trazabilidad
            // ya que el jugador se queda sin el trait que tuviese
            item.setConcepto( "serial: " + item.getJugador().getId() + " slot: " + p_slot +" previo: " + trait_anterior );            
        }
        return 0;
    }

    
    
    private EquipoGashaball buscaEquipoGashaball ( EntityManager emt, int p_equipo_id, short p_gashaball_id ) {
        List<EquipoGashaball>       lista_eq_ga     =null;

        // Buscamos equipo_gashaball para incrementar el credito
        Query q = emt.createNamedQuery("EquipoGashaball.findByEquipoIdGashaballId");
        q.setParameter("equipoId",    p_equipo_id    );
        q.setParameter("gashaballId", p_gashaball_id );

        lista_eq_ga = q.getResultList();

        if ( lista_eq_ga.isEmpty() )
            return null;
        else
            return lista_eq_ga.get(0);
    }


    private int AzarCarta (  EntityManager emt, int p_rareza, int p_nivel)  throws ExcepcionGeneral {
        /* busca una carta al azar de la rareza y nivel (511)*/
         List<Carta> lista_carta=null;

        Query q1 = emt.createNamedQuery("Carta.findBySobre");
        q1.setParameter("nivel"   , p_nivel);
        q1.setParameter("rareza"  , p_rareza);

        lista_carta = q1.getResultList();

        if ( lista_carta.isEmpty() ) {
            Query q2 = emt.createNamedQuery("Carta.findBySobre");
            q2.setParameter("nivel"   , 511);
            q2.setParameter("rareza"  , p_rareza);

            log.debug("[!!!No encontrado buscamos NIVEL 1!!!]: " + p_nivel + "rareza" + (short)p_rareza );

            lista_carta = q2.getResultList();

            if ( lista_carta.size() == 0) {
                throw new ExcepcionGeneral( -14, "No existe carta Nivel 1" );
            }
        }

        Random rnd = new Random ();
        int n = (int)(rnd.nextDouble() * (float)lista_carta.size());

        Carta objeto = lista_carta.get(n);

        return objeto.getId();
    }


    private int AzarNivel ( Item p_item, int p_categoria ) {
            Random rnd = new Random ();

            int n = (int)(rnd.nextDouble() * 100.0);

            int nivel = 515;
            switch ( p_categoria ) {
                case 5501: // Sobre 1 estrella
                    if ( n<61 ) {
                        nivel = 511;
                    }  else if (n<85 ){
                        nivel = 512;
                    } else if (n<95 ){
                        nivel = 513;
                    } else if (n<99) {
                        nivel = 514;
                    }
                    break;
                case 5502: // Sobre 2 estrellas
                    if ( n<11 ) {
                        nivel = 511;
                    }  else if (n<33 ){
                        nivel = 512;
                    } else if (n<83 ){
                        nivel = 513;
                    } else if (n<96) {
                        nivel = 514;
                    }
                    break;
                case 5503: // Sobre 3 estrellas
                    if ( n<6 ) {
                        nivel = 511;
                    }  else if (n<16 ){
                        nivel = 512;
                    } else if (n<41 ){
                        nivel = 513;
                    } else if (n<86) {
                        nivel = 514;
                    }
                    break;
            }
            return nivel;
    }


//    private int ComprarCarta( EntityManager emt, Item item, int p_equipo_id, short p_unidades ) throws ExcepcionGeneral {
    private int ComprarCarta( EntityManager emt, Item item ) throws ExcepcionGeneral {
log.debug("[TRAZA][COMPRAR CARTA]: " + item.getEquipo().getId() + " " + item.item_id + " " + item.getUnidades() );

//        int retorno = GuardarCartaInventario( emt, item, p_equipo_id, p_unidades );
        int retorno = GuardarCartaInventario( emt, item );

        if ( retorno != 0)
            return retorno;

        if ( item.stock != -1 ) {
            if ( item.stock-item.vendidas < item.getUnidades() ) {
                log.error("[ERROR][Stock Insuficiente]: " );
                throw new ExcepcionGeneral( -20, "Stock exhausted" );
                //return -20; /* stock insuficiente */
            }
        }

log.debug("[TRAZA][OBJETO GUARDAR STOCK ]: " );

        return 0;
    }

//    int GuardarCartaInventario( EntityManager emt, Item item, int p_equipo_id, short p_unidades ) throws ExcepcionGeneral {
    int GuardarCartaInventario( EntityManager emt, Item item ) throws ExcepcionGeneral {
log.debug("[TRAZA][GUARDAR CARTA INVENTARIO]: " + item.getEquipo().getId() + " " + item.item_id + " " + item.getUnidades());

        Query q1 = emt.createNamedQuery("Carta.findById");
        q1.setParameter("id"   , item.item_id);

        List<Carta> lista_carta = q1.getResultList();
        if ( lista_carta.isEmpty() )
            throw new ExcepcionGeneral( -19, "Item identifier not found" );
            //return -3;

        Carta objeto = lista_carta.get(0);

        item.asignarValores( //p_equipo_id, p_unidades,
                             objeto.getPrecio(),objeto.getPuntos(),
                             objeto.getStockTotal(),objeto.getVendidas(),
                             objeto.getNivel(),objeto.getUdsEquipo(), // No hay límite en los gashaballs
                             objeto.getFIni(),objeto.getFFin(),
                             objeto.getEstado(),0
                             );
/*
        // Si no es una carta que se venda en tienda rechazamos
        if ( p_es_compra_tienda == true && objeto.getEstado()!= 1 && objeto.getEstado()!= 3) {
            log.error("Card not for sale" + item.item_id + " equipo " + p_equipo_id);
            throw new ExcepcionGeneral( -4, "Card not for sale" );
            //return -4;
        }
*/

        /* Comprobamos si sobrepasa máx uds equipo */
        CartaEquipo equipo_objeto=null;
        CartaEquipo nuevo = new CartaEquipo();

        Query q = emt.createNamedQuery("CartaEquipo.findByEquipoIdCartaId");
        q.setParameter("equipoId"   , item.getEquipo().getId() );
        q.setParameter("cartaId"    ,item.item_id);

        List<CartaEquipo> lista = q.getResultList();

        if ( !lista.isEmpty() ) {
            /* Actualizamos el numero de objetos del almacen del equipo */
            equipo_objeto = lista.get(0);

/*          item.unidades_equipo_actuales += equipo_objeto.getCantidad();
            equipo_objeto.setCantidad( item.unidades_equipo_actuales );   */

            equipo_objeto.setCantidad( (short) (equipo_objeto.getCantidad() + item.getUnidades()) );
            item.unidades_equipo_actuales = equipo_objeto.getCantidad();
        } else {
            /* Añadimos el objeto al almacen del equipo */
            CartaEquipoPK pk = new CartaEquipoPK ( );
            pk.setEquipoId(item.getEquipo().getId() );
            pk.setCartaId(item.item_id);

            nuevo.setCartaEquipoPK ( pk );
            nuevo.setCantidad( (short)item.getUnidades() );

            emt.persist(nuevo);
            item.unidades_equipo_actuales = (short)item.getUnidades();

        }

        /* decrementar stock */
        if ( objeto.getStockTotal() != -1) {
            log.debug(" OBJETO DE STOCK LIMITADO" + item.item_id + " equipo " + item.getEquipo().getId() );
            objeto.setVendidas(item.vendidas + item.getUnidades() );
        }

        return 0;
    }

    public int PasarCartaMazoInventario( EntityManager emt, Mazo p_mazo ) {
log.debug("[TRAZA][PASO CARTA DE MAZO A INVENTARIO]: " + p_mazo.getMazoPK().getEquipoId() + " " + p_mazo.getCarta().getId() );

        /* Comprobamos si sobrepasa máx uds equipo */
        CartaEquipo equipo_objeto=null;
        CartaEquipo nuevo = new CartaEquipo();

        Query q = emt.createNamedQuery("CartaEquipo.findByEquipoIdCartaId");
        q.setParameter("equipoId"   , p_mazo.getMazoPK().getEquipoId());
        q.setParameter("cartaId"    , p_mazo.getCarta().getId());

        List<CartaEquipo> lista = q.getResultList();

        if ( !lista.isEmpty() ) {
            /* Actualizamos el numero de objetos del almacen del equipo */
            equipo_objeto = lista.get(0);

            equipo_objeto.setCantidad( (short) (equipo_objeto.getCantidad() + 1 ) );

log.debug("Aumentando CartaEquipo " + equipo_objeto.getCartaEquipoPK().getEquipoId() +" carta " +  equipo_objeto.getCartaEquipoPK().getCartaId()  );
        } else {

            /* Añadimos el objeto al almacen del equipo */
            CartaEquipoPK pk = new CartaEquipoPK ( );
            pk.setEquipoId( p_mazo.getMazoPK().getEquipoId());
            pk.setCartaId( p_mazo.getCarta().getId());
            nuevo.setCartaEquipoPK ( pk );
            nuevo.setCantidad( (short)1 );
log.debug("Creando CartaEquipo " + p_mazo.getMazoPK().getEquipoId()+ " carta" +  p_mazo.getCarta().getId());

            emt.persist(nuevo);
        }
        return 0;
    }


//    private int ComprarRopa( EntityManager emt, Item item, int p_equipo_id, short p_unidades ) throws ExcepcionGeneral{
    private int ComprarRopa( EntityManager emt, Item item ) throws ExcepcionGeneral{

//        int retorno = GuardarRopaInventario( emt, item, p_equipo_id, p_unidades );
        int retorno = GuardarRopaInventario( emt, item );

        if ( retorno != 0)
            return retorno;

        if ( item.stock != -1 ) {
            if ( item.stock-item.vendidas < item.getUnidades() ) {
                log.error("[ERROR][Stock Insuficiente]: " );
                throw new ExcepcionGeneral( -20, "Stock exhausted" );
                // return -20; /* stock insuficiente */
            }
        }

        if ( item.getUdsEquipo()>-1) {
            item.unidades_equipo_actuales = 0;

            // Contamos las unidades que hay en el armario
            Query q = emt.createNamedQuery("ArmarioEquipo.findByEquipoIdRopaId");
            q.setParameter("equipoId"   , item.getEquipo().getId() );
            q.setParameter("ropaId"     , item.item_id);

            List<ArmarioEquipo> lista = q.getResultList();
            if ( !lista.isEmpty() ) {
                item.unidades_equipo_actuales = lista.get(0).getCantidad();
            }

            // Contamos las unidades que llevan vestidas los jugadores del equipo
            Query q2 = emt.createNamedQuery("RopaJugador.findByEquipoId");
            q2.setParameter("equipoId"   , item.getEquipo().getId() );
            q2.setParameter("ropaId"     , item.item_id);

            List<RopaJugador> lista_ropa = q2.getResultList();
            if ( !lista_ropa.isEmpty() ) {
                item.unidades_equipo_actuales += lista_ropa.size();
            }
        }
        return 0;
    }

//    int GuardarRopaInventario( EntityManager emt, Item item, int p_equipo_id, short p_unidades ) throws ExcepcionGeneral {
    int GuardarRopaInventario( EntityManager emt, Item item ) throws ExcepcionGeneral {
log.debug("[TRAZA][GuardarRopaInventorio]: " + item.getEquipo().getId() + ", " + item.item_id );
        Ropa objeto = emt.find(Ropa.class, item.item_id);
        if ( objeto == null) 
            throw new ExcepcionGeneral( -19, "Item identifier not found" );
            //return -3;

        item.asignarValores( 
                             objeto.getPrecio(),objeto.getPuntos(),
                             objeto.getStockTotal(),objeto.getVendidas(),
                             objeto.getNivel(),objeto.getUdsEquipo(), 
                             objeto.getFIni(),objeto.getFFin(),
                             objeto.getEstado(),objeto.getDias()
                             );

        if ( objeto.getDias()>0 ) {
            /* Objeto con caducidad */
            GuardaRopaInstancia(emt, item, objeto);
        } else {
            /* Objeto normal */
            GuardaRopaArmario( emt, item);
        }

        if ( item.stock != -1 ) {
            if ( item.stock-item.vendidas < item.getUnidades() ) {
                log.error("[ERROR][Stock Insuficiente]: " );
                throw new ExcepcionGeneral( -20, "Stock exhausted" );
                //return -20; /* stock insuficiente */
            }
        }

        /* decrementar stock */
        if ( objeto.getStockTotal() != -1) {
log.debug(" OBJETO DE STOCK LIMITADO");
            objeto.setVendidas(item.vendidas + item.getUnidades() );
        }

        return 0;
    }

    private int GuardaRopaArmario( EntityManager emt, Item item ) {

        /* Comprobamos si sobrepasa máx uds equipo */
        ArmarioEquipo equipo_objeto=null;
        ArmarioEquipo nuevo = new ArmarioEquipo();

        Query q = emt.createNamedQuery("ArmarioEquipo.findByEquipoIdRopaId");
        q.setParameter("equipoId"   , item.getEquipo().getId() );
        q.setParameter("ropaId"     , item.item_id);

        List<ArmarioEquipo> lista = q.getResultList();

        if ( !lista.isEmpty() ) {
            /* Incrementamos armario */
            equipo_objeto = lista.get(0);

/*          item.unidades_equipo_actuales += equipo_objeto.getCantidad();
            equipo_objeto.setCantidad( item.unidades_equipo_actuales ); */

            equipo_objeto.setCantidad( (short) (equipo_objeto.getCantidad() + item.getUnidades() ) );
            item.unidades_equipo_actuales = equipo_objeto.getCantidad();

            log.debug("[TRAZA][ArmarioEquipo Encontrado]: " + equipo_objeto.getArmarioEquipoPK().getEquipoId() + " "  );
        } else {
            item.unidades_equipo_actuales = (short)item.getUnidades();

            /* Añadimos la prenda al armario */
            ArmarioEquipoPK pk = new ArmarioEquipoPK ( );
            pk.setEquipoId(item.getEquipo().getId());
            pk.setRopaId(item.item_id);

            nuevo.setArmarioEquipoPK ( pk );
            nuevo.setCantidad( (short)item.getUnidades() );
            emt.persist(nuevo);

            log.debug("[TRAZA][ArmarioEquipo No Encontrado]: " + item.getEquipo().getId() + ", " + item.item_id );
        }
        return 0;
    }

    private int GuardaRopaInstancia( EntityManager emt, Item item, Ropa p_ropa ) {
        /* Comprobamos si sobrepasa máx uds equipo */
        /* OJO NO ESTA HECHA LA COMPROBACION PARA ITEMS CADUCABLES */

        int unidades_comprar=item.getUnidades();

        for ( int i=0;i<unidades_comprar;i++ ) {
            // Creamos un nuevo RopaInstancia
            RopaInstancia instancia = new RopaInstancia();

            instancia.setEquipoId   (item.getEquipo());
            instancia.setFCompra    ( new Date());
            instancia.setFCaduca    ( Util.FechaSiguiente ( item.dias ) ); //OJO INCREMENTAR
            instancia.setRopa       (p_ropa);
            instancia.setUsos       ((short) -1);
            instancia.setJugadorId  (null);

            emt.persist (instancia);

            item.addInstancia(instancia);
            //item.setInstancia(instancia);
        }
        return 0;

    }


    private int ultimaDemarcacion( EntityManager emt, int p_equipo_id ) {
        PlantillaPK pk = new PlantillaPK ( );
        pk.setEquipoId (p_equipo_id);

        Query q = emt.createNamedQuery("Plantilla.findMaxDemarcacionByEquipo");
        q.setParameter("equipoId", pk.getEquipoId());

        List<Plantilla> lista = q.getResultList();
        if ( !lista.isEmpty() ) {
            /* Incrementamos armario */
            Plantilla jugador = lista.get(0);
log.debug("[TRAZA][Ultima Demarcacion]: " + jugador.getDemarcacion());
            return jugador.getDemarcacion()+1;
        } else {
            return 1;
        }
    }

    private short dorsalLibre ( EntityManager emt, int p_equipo_id ) {

        PlantillaPK pk = new PlantillaPK ( );
        pk.setEquipoId (p_equipo_id);

        Query q = emt.createNamedQuery("Plantilla.findMaxDorsalByEquipo");
        q.setParameter("equipoId", pk.getEquipoId());

        List<Plantilla> lista = q.getResultList();

        if ( !lista.isEmpty() ) {
            /* Incrementamos armario */
            Plantilla jugador = lista.get(0);

            short aux_retorno = jugador.getPlantillaPK().getDorsal();
            aux_retorno += 1;
            
            if ( aux_retorno == 100 ) {
                aux_retorno = 1;
                boolean encontrado = true;
                
                while ( encontrado == true ) {
                    Query q2 = emt.createNamedQuery("Plantilla.findByDorsal");
                    q2.setParameter("equipoId", pk.getEquipoId());
                    q2.setParameter("dorsal", aux_retorno);

                    try {
                        List<Plantilla> otra_lista = q2.getResultList();
                        if ( otra_lista == null || otra_lista.size()==0 ) {
                            encontrado=false;
                        } else {
                            encontrado=true;
                            aux_retorno += 1;
                        }
                        
                    } catch (NoResultException nre) {
                        encontrado=false;
                    } 
                }                
            }
            

log.debug("[TRAZA][Ultimo Dorsal]: " + aux_retorno);

            return aux_retorno ;
        }

        return 0;
    }

    /* Venta de un objeto
     *
     *
     *  -3, "El equipo no tiene el objeto"
     *  -5 - Sesion incorrecta
     *  -4 - Equipo no corresponde a sesión de usuario
     * -12 - No existe el equipo
     * -13 - Importe desactualizado

     // comunes
     * -14 - El equipo no tiene suficientes unidades del objeto
     * -19 - Item identifier not found
     * -23 - No se puede vender ropa vestida por un jugador
     * -31 - El jugador es titular
     * -32 - Instancia jugador no existe
     * -33 -No existe el Modelo de Jugador
     
     // solo para venta de jugadores
      -31, "El jugador es titular
      -32, "Instancia jugador no existe
      -33, "No existe el Modelo de Jugador
     */

    public String vender( String p_sesion, int p_equipo_id,
                        short p_objeto_tipo, int p_objeto_id, 
                        short p_unidades, int juego_id, int p_importe_esperado) {
        String retorno = "";
        int codError = -1;
        EntityManager emt = null;
        int             aux_usuario_id  = -1;
        Equipo          aux_equipo      = null;
        Usuario         aux_usuario     = null;
        Item            item = new Item ();
        java.util.Date  f_actual=new java.util.Date();


        try {
            emt = emfTienda.createEntityManager(); // check 07.08.2012

            LoginAction la = new LoginAction();
            aux_usuario_id = la.comprobarSesionEquipo(p_sesion,p_equipo_id,emt);
            if ( aux_usuario_id <0 ) {
                log.error("Sesión Incorrecta "+p_sesion+" "+p_equipo_id);
                return "error=-5";
            }

            emt.getTransaction().begin();

            aux_equipo  = emt.find(Equipo.class, p_equipo_id);
            if ( aux_equipo == null) {
                throw new ExcepcionGeneral( -12, "No existe el equipo" );
            } else {
log.debug("[TRAZA][USUARIO EQUIPO VENDER]: " + aux_equipo.getUsuario().getNick() + " " + aux_equipo.getUsuario().getCreditos() );
log.debug("[TRAZA][TIPO_OBJETO]: " + p_objeto_tipo + " [ID]: " + p_objeto_id + " [UDS]: " + p_unidades );
                aux_usuario = aux_equipo.getUsuario();

                // ERROR: Si no coincide el propietario del equipo con la sesión pasada
                if ( aux_usuario.getId() != aux_usuario_id)
                    throw new ExcepcionGeneral( -4, "Sesion y Equipo de diferente propietario" );
           }

            switch ( p_objeto_tipo ) {
                case 1: // modelo jugador
                    codError  = VenderMJugador( emt, aux_equipo, item, p_objeto_id, p_unidades );
                break;
                case 2: // ropa
                    codError = VenderRopa    ( emt, p_equipo_id, item, p_objeto_id, p_unidades );
                break;
                case 3: // objeto
                    /* PROVISIONAL, solo se puede comprar un objeto por categoria por ahora,
                     * por lo tanto se venderá previamente el que el usuario  tenga en su almacen
                     * antes de comprar el nuevo.
                     */
                    codError = VenderObjeto  ( emt, p_equipo_id, item, p_objeto_id, p_unidades );
                break;
                case 5: // carta
                    codError = VenderCarta  ( emt, p_equipo_id, item, p_objeto_id, p_unidades );
                    break;
                case 6: // entrenador
                    break;
                case 9: // los sobres no se devuelven
                default:
                    // ERROR: tipo de objeto no soportado
                    codError = -5;
                    break;
            }

            if ( codError != 0 ) {
                    log.error("[TRAZA][ERROR_VENDER]: " + retorno );
                    throw new ExcepcionGeneral( codError, "Error al vender" );
            }
            /* Creditos a devolver al usuario, normalmente el 50% del coste
             * actual del objeto/ropa
             */

            /* Inserto un nuevo movimiento */
            Movimiento movimiento = new Movimiento();
            movimiento.setUsuarioId (aux_usuario_id);
            movimiento.setEquipoId  (p_equipo_id);

            movimiento.setTipo  ((short)2); // devolucion
            movimiento.setFAlta (f_actual);
            movimiento.setJuegoId (juego_id);
//            movimiento.setValor ( (p_unidades * (item.creditos*0.2f)));
            // Nunca devolvemos Bitoones, devolvemos puntos
            movimiento.setValor ( 0 );
            movimiento.setConcepto(item.getConcepto());

            /* Si un articulo tiene precio en Bitoones y/o Dudies, se devuelve integro en Dudies
             * si un articulo tiene precio solo en Dudies, se devuelve el 10% en Dudies
             */
            int puntos_devolver;
            if ( item.creditos > 0 && item.puntos == 0 ) {
                puntos_devolver = (int)(p_unidades * (item.creditos));
            } else {
                puntos_devolver = (int)(p_unidades * item.puntos * 0.1f);
            }

            // if ( p_importe_esperado> -1 && p_importe_esperado != puntos_devolver ) {
            // 2012-04-19 Arreglo de venta de objetos multiples
            // 2012-04-30 Arreglo venta de objetos multiples, en lugar del importe unitario esperado,
            // ahora recibimos el importe total que esperamos sea devuelto.
            // if ( p_importe_esperado *(int)p_unidades > -1 &&
            //      p_importe_esperado *(int)p_unidades != puntos_devolver ) {
            if ( p_importe_esperado > -1 &&
                 p_importe_esperado  != puntos_devolver ) {

                throw new ExcepcionGeneral( -13, "Importe desactualizado ->" +
                        aux_usuario.getId() + " " + p_importe_esperado*(int)p_unidades + " " + puntos_devolver   );
            }

            movimiento.setPuntos( puntos_devolver);

            movimiento.setItemTipo  (p_objeto_tipo);
            movimiento.setItemId    (p_objeto_id);
            movimiento.setItemUds   (p_unidades);

            emt.persist( movimiento);
log.debug("[TRAZA][MOVIMIENTO GUARDADO]: "
             + " $:"  + movimiento.getValor()
             + " pt:" + movimiento.getPuntos()
             + " ud:" + movimiento.getItemUds());

         /* Actualizo el crédito y los puntos del usuario */
log.debug("[TRAZA][creditos]: " +  aux_usuario.getCreditos()  + " " + movimiento.getValor() );
log.debug("[TRAZA][puntos]: "   +  aux_equipo.getPuntos()     + " " + movimiento.getPuntos() );

            /* Guardamos el saldo resultante de la operacion */
            movimiento.setSaldoDinero(aux_usuario.getCreditos() + movimiento.getValor());
            movimiento.setSaldoPuntos(aux_equipo.getPuntos()    + movimiento.getPuntos());

            aux_usuario.setCreditos( (float)aux_usuario.getCreditos()   + (float)movimiento.getValor() );
            aux_equipo.setPuntos   ( (int)  aux_equipo.getPuntos()      + (int)  movimiento.getPuntos() );

log.debug("[TRAZA][creditos]: " +  aux_usuario.getCreditos()  + " devuelto: " + item.creditos );
log.debug("[TRAZA][creditos]: " +  aux_usuario.getCreditos()  + " " + movimiento.getValor() );
log.debug("[TRAZA][puntos]: "   +  aux_equipo.getPuntos()    + " " + movimiento.getPuntos() );

            emt.getTransaction().commit();

            log.debug("[TRAZA][COMMIT]" );
            return "error=0;credito=" + aux_usuario.getCreditos() + ";puntos=" + aux_equipo.getPuntos()+ ";";

        } catch (ExcepcionGeneral ex) {
            log.error("[ERROR][vender]: " , ex);

            retorno = "error="+ex.getCodigo()+";descripcion="+ex.getDescripion()+ ";";
            if ( emt != null && emt.getTransaction().isActive() )
                emt.getTransaction().rollback();
        } finally {
            try { if (emt != null) emt.close(); }
            catch (Exception e) {
                log.error("[ERROR][constructor]: EMT base de datos: " , e);
            }
        }

        return retorno;
    }

    private int VenderObjeto( EntityManager emt, int p_equipo_id, Item p_item, int p_objeto_id, short p_unidades ) throws ExcepcionGeneral {

        Objeto objeto  = emt.find(Objeto.class, p_objeto_id);
        if ( objeto == null) 
            throw new ExcepcionGeneral( -19, "Item identifier not found" );

        EquipoObjeto equipo_objeto=null;

        Query q = emt.createNamedQuery("EquipoObjeto.findByEquipoIdObjetoId");
        q.setParameter("equipoId"   , p_equipo_id);
        q.setParameter("objetoId"   , p_objeto_id);

        List<EquipoObjeto> lista = q.getResultList();
        if ( lista.isEmpty() == true ) {
            throw new ExcepcionGeneral( -3, "El equipo no tiene el objeto" );
        } else {
            equipo_objeto= lista.get(0);
        }
log.debug("[TRAZA][EQUIPO_OBJETO_ENCONTRADO]: " +  equipo_objeto.getCantidad() );

        if ( equipo_objeto.getCantidad() < p_unidades) {
            throw new ExcepcionGeneral( -14, "El equipo no tiene suficientes unidades del objeto" );
        }

        if ( equipo_objeto.getCantidad() - p_unidades == 0) {
            /* borramos equipo objeto */
            emt.remove(equipo_objeto);
        } else {
            /* Actualizamos las unidades */
            equipo_objeto.setCantidad( (short) (equipo_objeto.getCantidad() - p_unidades) );
        }

log.debug("[TRAZA][EQUIPO_OBJETO_DECRMENTADO]: " +  equipo_objeto.getCantidad() );

        /* incrementar devoluciones solo objetos de stock controlado*/
        if ( objeto.getStockTotal() != -1) {
log.debug(" OBJETO DE STOCK LIMITADO");
            objeto.setDevueltas( objeto.getDevueltas() + p_unidades);
        }

        p_item.creditos = objeto.getPrecio() ;
        p_item.puntos   = objeto.getPuntos() ;

        /* VOLVER A AUMENTAR EL STOCK NO ESTA CLARO */

        return 0;

    }

    private int VenderRopa( EntityManager emt, int p_equipo_id, Item p_item, int p_objeto_id, short p_unidades ) throws ExcepcionGeneral {
        Vestidor        vestidor        = new Vestidor();
        Ropa            obj_ropa        = null;
        RopaInstancia   ropa_instancia  = null;

        if ( p_objeto_id < 0 ) {
log.debug("[VenderRopa][Instancia] " + p_objeto_id );
            // Se trata de una instancia de objeto
            ropa_instancia = vestidor.buscarInstancia(emt,Math.abs(p_objeto_id) );
            if ( ropa_instancia.getJugadorId() != null ) {
                throw new ExcepcionGeneral( -23, "No se puede vender ropa vestida por un jugador" );
            }
            obj_ropa = ropa_instancia.getRopa();

        } else {
log.debug("[Vender Ropa][Normal] " + p_objeto_id );
            obj_ropa = emt.find(Ropa.class, p_objeto_id);
            if ( obj_ropa != null) {
                ArmarioEquipo armario_equipo=null;

                Query q = emt.createNamedQuery("ArmarioEquipo.findByEquipoIdRopaId");
                q.setParameter("equipoId"   , p_equipo_id);
                q.setParameter("ropaId"   , p_objeto_id);

                List<ArmarioEquipo> lista = q.getResultList();
                if ( lista.isEmpty() == true ) {
                    throw new ExcepcionGeneral( -3, "El equipo no tiene la ropa equipo:" + p_equipo_id + " ropa: " + p_objeto_id);
                } else {
                    armario_equipo= lista.get(0);
                }
log.debug("[TRAZA][EQUIPO_OBJETO_ENCONTRADO]: " +  armario_equipo.getCantidad() );

                if ( armario_equipo.getCantidad() < p_unidades) {
                    throw new ExcepcionGeneral( -14, "El equipo no tiene suficientes unidades de la ropa" );
                }

                if ( armario_equipo.getCantidad() - p_unidades == 0) {
                    /* borramos equipo objeto */
                    emt.remove(armario_equipo);
                } else {
                    /* Actualizamos las unidades */
                    armario_equipo.setCantidad( (short) (armario_equipo.getCantidad() - p_unidades) );
                }

log.debug("[TRAZA][ARMARIO_EQUIPO_DECRMENTADO]: " +  armario_equipo.getCantidad() );

            }
        }

        // VOLVER A AUMENTAR EL STOCK NO ESTA CLARO
        if ( obj_ropa != null ) {
            // incrementar devoluciones solo objetos de stock controlado
            if ( obj_ropa.getStockTotal() != -1) {
log.debug(" OBJETO DE STOCK LIMITADO");
                obj_ropa.setDevueltas( obj_ropa.getDevueltas() + p_unidades);
            }

            p_item.creditos = obj_ropa.getPrecio() ;
            p_item.puntos   = obj_ropa.getPuntos() ;

            // Si es una instancia y han pasado 24 horas desde la compra no devolvemos nada
            if ( ropa_instancia != null ) {
                if ( ropa_instancia.getFCompra().compareTo( Util.FechaSiguiente(-1) ) < 0 ) {
                    p_item.creditos = 0 ;
                    p_item.puntos   = 0 ;
log.debug(" NO DEVOLVEMOS NADA, HAN TRANSCURRIDO 24 HORAS");
                }
                emt.remove( ropa_instancia );
            }
        } else {
            throw new ExcepcionGeneral( -19, "Item identifier not found" );
        }
        return 0;

    }

    private int VenderMJugador( EntityManager emt, Equipo p_equipo, Item p_item, int p_objeto_id, short p_unidades ) throws ExcepcionGeneral {
log.debug("[TRAZA][VENDER JUGADOR]: " +  p_objeto_id );

        int demarcacion;

        /* Si el jugador tiene ropa la pasamos al armario */
        Hashtable <Short,Integer> ropa_jugador = new Hashtable();
        Vestidor vestidor= new Vestidor();
        for ( short i=1;i<=7;i++ ) {
            ropa_jugador.put(i, 0);
        }
        // El parametro con valor significa operacion venderMJugador
        vestidor.vestirJugador( emt, p_objeto_id, ropa_jugador, 2 );

        /* Sacamos al jugador del equipo */
        Plantilla plantilla  = null;
        int       encontrado = 0;
        Query q = emt.createNamedQuery("Plantilla.findByEquipoId");
        q.setParameter("equipoId"    , p_equipo.getId());
        List<Plantilla> lista = q.getResultList();
        if ( lista.isEmpty() == false ) {
            for ( int i=0;i<lista.size();i++) {
                if ( lista.get(i).getJugador().getId() == p_objeto_id) {
                    plantilla=lista.get(i);
                    if ( plantilla.getTitular() == 1) 
                        throw new ExcepcionGeneral( -31, "El jugador es titular" );
                }
                if ( plantilla != null) {
                    lista.get(i).setDemarcacion( (short)(lista.get(i).getDemarcacion() -1));
                }
            }
        }
        if ( plantilla == null )
            throw new ExcepcionGeneral( -3, "El equipo no tiene al jugador" );

        emt.remove(plantilla);

        /* Busco al Jugador para saber cual es su modelo */
        Jugador jugador = emt.find( Jugador.class, plantilla.getPlantillaPK().getJugadorId());
        if ( jugador == null ) {
            throw new ExcepcionGeneral( -32, "Instancia jugador no existe" );
        }
        jugador.setEquipo(null);
        jugador.setEstado((short)2); /* ponemos el jugador a retirado */

        vestidor.calcularPowerPlay(emt, p_equipo);

        /* Buscamos el modelo */
        MJugador objeto  = emt.find(MJugador.class, jugador.getMJugador().getId());
        if ( objeto == null) {
            throw new ExcepcionGeneral( -33, "No existe el Modelo de Jugador" );
        }

log.debug("[TRAZA][MJUGADOR_DECREMENTADO]: " + objeto.getId() + " dinero " + objeto.getPrecio() + "puntos " + objeto.getPuntos());

        /* incrementar devoluciones solo objetos de stock controlado*/
        if ( objeto.getStockTotal() != -1) {
log.debug(" OBJETO DE STOCK LIMITADO");
            objeto.setDevueltas( objeto.getDevueltas() + p_unidades);
        }

        p_item.creditos = objeto.getPrecio() ;
        p_item.puntos   = objeto.getPuntos() ;

        // Guardamos el identificador de jugador en el concepto para aumentar la trazabilidad
        // ya que el jugador se queda sin equipo asignado
        p_item.setConcepto( "serial: " + jugador.getId() );
        
        return 0;
    }

    private int VenderCarta( EntityManager emt, int p_equipo_id, Item p_item, int p_objeto_id, short p_unidades ) throws ExcepcionGeneral {

        Carta objeto  = emt.find(Carta.class, p_objeto_id);
        if ( objeto == null) 
            throw new ExcepcionGeneral( -19, "Item identifier not found" );

        // Sacamos la carta del inventario
        Cartas cartas = new Cartas();
        cartas.sacarCartaInventario ( emt, p_equipo_id, objeto.getId(), (int)p_unidades);

        /* incrementar devoluciones solo objetos de stock controlado*/
        if ( objeto.getStockTotal() != -1) {
log.debug(" OBJETO DE STOCK LIMITADO");
            objeto.setDevueltas( objeto.getDevueltas() + p_unidades);
        }

        p_item.creditos = objeto.getPrecio() ;
        p_item.puntos   = objeto.getPuntos() ;

        return 0;
    }


    /**************************************************
     * FUNCIONES DE CONSULTA
     **************************************************/
/*
 * SE HA LLEVADO A TiendaXML
 * 
    public String consultarCategoria ( HttpServletRequest request, HttpServletResponse response) {

        EntityManager   em          = null;
        XMLOutputter    out         = null;
        Document        doc         = null;
        Query           q           = null; 
        int             error       = 0;
        int             idCategoria = 0;

        try {
            em= emfTienda.createEntityManager(); // check 07.08.2012

            // Si no se envía parametro se busca la categoría raiz 
            if ( request.getParameter("idCategoria") != null ) {
                idCategoria = Integer.parseInt(request.getParameter("idCategoria"));

                q = em.createNamedQuery("Objeto.findByPadreId");
                q.setParameter("padreId", idCategoria);
            } else {
                q = em.createNamedQuery("Categoria.findAll");
            }
            List<Categoria> lista = q.getResultList();

            if (lista.isEmpty()) {
log.debug("[TRAZA][NO hay categorias asociadas]: " + idCategoria);
               error=-1; // No encontrado
            }

            // componemos el xml 
            Element root=new Element("consultarCategorias");
            Element el_error=new Element("err");
            el_error.setAttribute("cod",new Integer(error).toString());
            root.addContent(el_error);
            if ( error == 0) {
                for ( int i=0;i< lista.size(); i++) {
                    Categoria row = lista.get(i);

                    Element elemento=new Element("categoria");
                    elemento.setAttribute("id",           String.valueOf(row.getId         ()));
                    elemento.setAttribute("nombre",       String.valueOf(row.getNombre     ()));
                    elemento.setAttribute("descripcion",  String.valueOf(row.getDescripcion()));
                    elemento.setAttribute("padre_id",     String.valueOf(row.getPadreId    ()));

                    root.addContent(elemento);
                }
            }
            doc=new Document(root);//Creamos el documento

            doc.setDocType(null);

            out=new XMLOutputter();
        } catch (Exception e) {
            try { em.getTransaction().rollback(); } catch (Exception e2) { }
            log.error("[consultarCategoria]: " , e);
//            pintarStackTrace(e.getStackTrace());

        } finally {
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }

        return out.outputString(doc);
    }

    public String consultarObjeto ( HttpServletRequest request, HttpServletResponse response) {

        EntityManager   em          = null;
        XMLOutputter    out         = null;
        Document        doc         = null;
        Query           q           = null;
        int             error       = 0;
        int             id          = 0;
        int             categoriaId = 0;

        try {
            em= emfTienda.createEntityManager(); // check 07.08.2012

            // Si se envía el identificador de un artículo se busca por el
            if ( request.getParameter("id") != null ) {
                id = Integer.parseInt(request.getParameter("id"));
                q = em.createNamedQuery("Objeto.findById");
                q.setParameter("id", id);
            } else {
                // Si no se envía parametro se busca la categoría raiz 
                if ( request.getParameter("idCategoria") != null ) {
                    categoriaId = Integer.parseInt(request.getParameter("idCategoria"));
                    q = em.createNamedQuery("Objeto.findByCategoriaId");
                    q.setParameter("categoriaId", categoriaId);
                } else {
                    q = em.createNamedQuery("Objeto.findAll");
                }
            }
            List<Objeto> lista = q.getResultList();

            if (lista.isEmpty()) {
log.debug("[TRAZA][NO hay objetos] ");
               error=-1; // No encontrado
            }

            // componemos el xml 
            Element root=new Element("consultarObjetos");
            Element el_error=new Element("err");
            el_error.setAttribute("cod",new Integer(error).toString());
            root.addContent(el_error);
            if ( error == 0) {
                for ( int i=0;i< lista.size(); i++) {
                    Objeto row = lista.get(i);

                    Element elemento=new Element("objeto");

                    elemento.setAttribute("id",           String.valueOf(row.getId          ()));
                    elemento.setAttribute("nombre",       String.valueOf(row.getNombre      ()));
                    elemento.setAttribute("categoria_id", String.valueOf(row.getCategoria().getId ()));
                    elemento.setAttribute("coleccion_id", String.valueOf(row.getColeccion().getId ()));
                    elemento.setAttribute("precio",       String.valueOf(row.getPrecio      ()));
                    elemento.setAttribute("puntos",       String.valueOf(row.getPuntos      ()));
                    elemento.setAttribute("nivel",        String.valueOf(row.getNivel       ()));
                    elemento.setAttribute("stock_total",  String.valueOf(row.getStockTotal  ()));
                    elemento.setAttribute("vendidas",     String.valueOf(row.getVendidas    ()));
                    elemento.setAttribute("devueltas",    String.valueOf(row.getDevueltas   ()));
                    elemento.setAttribute("f_fin",        String.valueOf(row.getFFin        ()));
                    elemento.setAttribute("uds_equipo",   String.valueOf(row.getUdsEquipo   ()));

                    root.addContent(elemento);
                }
            }
            doc=new Document(root);//Creamos el documento

            doc.setDocType(null);

            out=new XMLOutputter();
        } catch (Exception e) {
            try { em.getTransaction().rollback(); } catch (Exception e2) { }
            log.error("[consultarObjeto]: " , e);
//            pintarStackTrace(e.getStackTrace());

        } finally {
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }

        return out.outputString(doc);
    }

    public String consultarTienda ( HttpServletRequest request, HttpServletResponse response) {
        EntityManager   em          = null;
        XMLOutputter    out         = null;
        Document        doc         = null;
        int             error       = 0;
        short           id          = 0;

        try {
log.debug("[TRAZA][Creo el entity Manager]");
            em= emfTienda.createEntityManager(); // check 07.08.2012

            // componemos el xml 
            Element root=new Element("consultarTienda");
            root.setAttribute("err", new Integer(error).toString());

            {
                // Buscamos todos los jugadores porque ahora puede haber jugadores
                // que no se puedan comprar pero que los usuarios los tengan como dark casanova
                Query q = em.createNamedQuery("MJugador.findActivosyOcultos");
                List<MJugador> lista = q.getResultList();

                if (!lista.isEmpty()) {
log.debug("[TRAZA][Lista Modelo Jugadores]");

                    for ( int i=0;i< lista.size(); i++) {
                        MJugador row = lista.get(i);

                        Element elemento=new Element("jugador");

                        elemento.setAttribute("id",             String.valueOf(row.getId            ()));
                        elemento.setAttribute("alias",          String.valueOf(row.getNombre        ()));
                        elemento.setAttribute("nombre_real",    String.valueOf(row.getNombreReal    ()));
                        elemento.setAttribute("apellido_real",  String.valueOf(row.getApellidoReal  ()));
                        elemento.setAttribute("escuela_id",     String.valueOf(row.getEscuela().getId()));
                        elemento.setAttribute("posicion1",      String.valueOf(row.getPosicion1     ()));
                        elemento.setAttribute("estado",         String.valueOf(row.getEstado                ()));

                        // Caracteristicas del jugador 
                        elemento.setAttribute("t1",             String.valueOf(row.getT1            ()));
                        elemento.setAttribute("t2",             String.valueOf(row.getT2            ()));
                        elemento.setAttribute("t3",             String.valueOf(row.getT3            ()));
                        elemento.setAttribute("agresividad",    String.valueOf(row.getAgresividad   ()));
                        elemento.setAttribute("driblin",        String.valueOf(row.getDriblin       ()));
                        elemento.setAttribute("pase",           String.valueOf(row.getPase          ()));
                        elemento.setAttribute("rebote_ataque",  String.valueOf(row.getReboteAtaque  ()));
                        elemento.setAttribute("rebote_defensa", String.valueOf(row.getReboteDefensa ()));
                        elemento.setAttribute("defensa",        String.valueOf(row.getDefensa       ()));
                        elemento.setAttribute("robo",           String.valueOf(row.getRobo          ()));
                        elemento.setAttribute("tapon",          String.valueOf(row.getTapon         ()));
                        elemento.setAttribute("resistencia",    String.valueOf(row.getResistencia   ()));
                        elemento.setAttribute("velocidad",      String.valueOf(row.getVelocidad     ()));
                        elemento.setAttribute("sprint",         String.valueOf(row.getSprint        ()));
                        elemento.setAttribute("teamwork",       String.valueOf(row.getTeamwork      ()));

                        elemento.setAttribute("precio",         String.valueOf(row.getPrecio        ()));
                        elemento.setAttribute("puntos",         String.valueOf(row.getPuntos        ()));
                        elemento.setAttribute("nivel",          String.valueOf(row.getNivel         ()));
                        elemento.setAttribute("nivel_ini",      String.valueOf(row.getNivelIni      ()));
                        elemento.setAttribute("nombre_interno", String.valueOf(row.getNombreInterno ()));
                        elemento.setAttribute("eti",            String.valueOf(row.getEtiqueta      ()));
                        
                        root.addContent(elemento);
                    }
                }
            }
            {
log.debug("[TRAZA][Lista Marcas]");
                Query q = em.createNamedQuery("Marca.findAll");
                List<Marca> lista = q.getResultList();

                if (!lista.isEmpty()) {
                    for ( int i=0;i< lista.size(); i++) {
                        Marca row = lista.get(i);

                        Element elemento=new Element("marca");

                        elemento.setAttribute("id",                 String.valueOf(row.getId            ()));
                        elemento.setAttribute("nombre",             String.valueOf(row.getNombre        ()));

                        root.addContent(elemento);
                    }
                }
            }
            {
log.debug("[TRAZA][Lista Colecciones]");
                Query q = em.createNamedQuery("Coleccion.findAll");
                List<Coleccion> lista = q.getResultList();

                if (!lista.isEmpty()) {
                    for ( int i=0;i< lista.size(); i++) {
                        Coleccion row = lista.get(i);

                        Element elemento=new Element("coleccion");

                        elemento.setAttribute("id",                 String.valueOf(row.getId            ()));
                        elemento.setAttribute("nombre",             String.valueOf(row.getNombre        ()));
                        elemento.setAttribute("marca_id",           String.valueOf(row.getMarcaId       ()));
                        root.addContent(elemento);
                    }
                }
            }

            {
log.debug("[TRAZA][Lista Escuelas]");
                Query q = em.createNamedQuery("Escuela.findAll");
                List<Escuela> lista = q.getResultList();

                if (!lista.isEmpty()) {
                    for ( int i=0;i< lista.size(); i++) {
                        Escuela row = lista.get(i);

                        Element elemento=new Element("escuela");

                        elemento.setAttribute("id",                 String.valueOf(row.getId            ()));
                        elemento.setAttribute("nombre",             String.valueOf(row.getNombre        ()));

                        root.addContent(elemento);
                    }
                }
            }

            {
log.debug("[TRAZA][Lista Sobres]");
                Query q = em.createNamedQuery("Sobre.findAll");
                List<Sobre> lista = q.getResultList();

                if (!lista.isEmpty()) {
                    for ( int i=0;i< lista.size(); i++) {
                        Sobre row = lista.get(i);

                        Element elemento=new Element("sobre");

                        elemento.setAttribute("id",             String.valueOf(row.getId            ()));
                        elemento.setAttribute("nombre",         String.valueOf(row.getNombre        ()));
                        elemento.setAttribute("categoria_id",   String.valueOf(row.getCategoriaId   ()));

                        // Atributos comunes de la tienda 
                        elemento.setAttribute("estado",         String.valueOf(row.getEstado        ()));
                        elemento.setAttribute("precio",         String.valueOf(row.getPrecio        ()));
                        elemento.setAttribute("puntos",         String.valueOf(row.getPuntos        ()));
                        elemento.setAttribute("nivel",          String.valueOf(row.getNivel         ()));
                        elemento.setAttribute("eti",            String.valueOf(row.getEtiqueta      ()));

                        root.addContent(elemento);
                    }
                }
            }
            {
log.debug("[TRAZA][Lista Gashaball]");
                Query q = em.createNamedQuery("Gashaball.findAll");
                List<Gashaball> lista = q.getResultList();

                if (!lista.isEmpty()) {
                    for ( int i=0;i< lista.size(); i++) {
                        Gashaball row = lista.get(i);

                        Element elemento=new Element("gashaball");

                        elemento.setAttribute("id",             String.valueOf(row.getId            ()));
                        elemento.setAttribute("nombre",         String.valueOf(row.getNombre        ()));
                        elemento.setAttribute("categoria_id",   String.valueOf(row.getCategoriaId   ()));

                        // Atributos comunes de la tienda 
                        elemento.setAttribute("estado",         String.valueOf(row.getEstado        ()));
                        elemento.setAttribute("precio",         String.valueOf(row.getPrecio        ()));
                        elemento.setAttribute("puntos",         String.valueOf(row.getPuntos        ()));
                        elemento.setAttribute("nivel",          String.valueOf(row.getNivel         ()));
                        elemento.setAttribute("eti",            String.valueOf(row.getEtiqueta      ()));

                        root.addContent(elemento);
                    }
                }
            }
            {
log.debug("[TRAZA][Lista GashaballPack]");
                Query q = em.createNamedQuery("GashaballPack.findAll");
                List<GashaballPack> lista = q.getResultList();

                if (!lista.isEmpty()) {
                    for ( int i=0;i< lista.size(); i++) {
                        GashaballPack row = lista.get(i);

                        Element elemento=new Element("gashaballpack");

                        elemento.setAttribute("id",             String.valueOf(row.getId            ()));
                        elemento.setAttribute("nombre",         String.valueOf(row.getNombre        ()));
                        elemento.setAttribute("categoria_id",   String.valueOf(row.getCategoriaId   ()));

                        // Atributos comunes de la tienda 
                        elemento.setAttribute("estado",         String.valueOf(row.getEstado        ()));
                        elemento.setAttribute("precio",         String.valueOf(row.getPrecio        ()));
                        elemento.setAttribute("puntos",         String.valueOf(row.getPuntos        ()));
                        elemento.setAttribute("nivel",          String.valueOf(row.getNivel         ()));
                        elemento.setAttribute("cantidad",       String.valueOf(row.getCantidad      ()));
                        elemento.setAttribute("gid",            String.valueOf(row.getGashaball().getId()));
                        elemento.setAttribute("eti",            String.valueOf(row.getEtiqueta      ()));

                        root.addContent(elemento);
                    }
                }
            }

            {
log.debug("[TRAZA][Lista Objeto]");
                Query q = em.createNamedQuery("Objeto.findAll");
                List<Objeto> lista = q.getResultList();

                if (!lista.isEmpty()) {
                    for ( int i=0;i< lista.size(); i++) {
                        Objeto row = lista.get(i);

                        Element elemento=new Element("objeto");

                        elemento.setAttribute("id",                 String.valueOf(row.getId                ()));
                        elemento.setAttribute("nombre",             String.valueOf(row.getNombre            ()));
                        if ( row.getColeccion() != null)
                            elemento.setAttribute("coleccion_id",   String.valueOf(row.getColeccion().getId ()));
                        elemento.setAttribute("tipo",               String.valueOf(row.getTipo              ()));

                        // Atributos comunes de la tienda
                        elemento.setAttribute("estado",         String.valueOf(row.getEstado        ()));
                        elemento.setAttribute("precio",         String.valueOf(row.getPrecio        ()));
                        elemento.setAttribute("puntos",         String.valueOf(row.getPuntos        ()));
                        elemento.setAttribute("nivel",          String.valueOf(row.getNivel         ()));
                        elemento.setAttribute("eti",            String.valueOf(row.getEtiqueta      ()));

                        root.addContent(elemento);
                    }
                }
            }


            {
log.debug("[TRAZA][Lista Gashaballitem]");
                Query q = em.createNamedQuery("Gashaballitem.findAll");
                List<Gashaballitem> lista = q.getResultList();

                if (!lista.isEmpty()) {
                    for ( int i=0;i< lista.size(); i++) {
                        Gashaballitem row = lista.get(i);

                        Element elemento=new Element("gashaballitem");

                        elemento.setAttribute("gashaball_id"    ,       String.valueOf(row.getGashaballId   ()));
                        elemento.setAttribute("item_type"       ,       String.valueOf(row.getItemType      ()));
                        elemento.setAttribute("item_id"         ,       String.valueOf(row.getItemId        ()));

                        root.addContent(elemento);
                    }
                }
            }

            {
log.debug("[TRAZA][Lista Uniformes]");
                Query q = em.createNamedQuery("CartaObjeto.findAll");
                List<CartaObjeto> lista = q.getResultList();

                if (!lista.isEmpty()) {
                    for ( int i=0;i< lista.size(); i++) {
                        CartaObjeto row = lista.get(i);

                        Element elemento=new Element("cu");

                        elemento.setAttribute("c"  , String.valueOf(row.getCarta().getId()));
                        elemento.setAttribute("t"  , String.valueOf(row.getObjectType()));
                        elemento.setAttribute("k"  , String.valueOf(row.getObjectId()));

                        root.addContent(elemento);
                    }
                }
            }

            doc=new Document(root);//Creamos el documento
            doc.setDocType(null);

            out=new XMLOutputter();
        } catch (Exception e) {
            log.error("[ERROR][consultarTienda]: ", e);
            try { em.getTransaction().rollback(); } catch (Exception e2) { }
        } finally {
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }

log.debug("[TRAZA][No Error]" + out.outputString(doc));
        return out.outputString(doc);
    }

    public String consultarCartas ( HttpServletRequest request, HttpServletResponse response) {
        EntityManager   em          = null;
        XMLOutputter    out         = null;
        Document        doc         = null;
        int             error       = 0;
        short           id          = 0;

log.debug("[consultarCartas Inicio]: " );

        try {
            em = emfTienda.createEntityManager(); // check 07.08.2012

            // componemos el xml 
            Element root=new Element("consultarCartas");
            root.setAttribute("err", new Integer(error).toString());

            Query q = em.createNamedQuery("Carta.findActivasyOcultas");
            List<Carta> lista = q.getResultList();

            if (!lista.isEmpty()) {
                for ( int i=0;i< lista.size(); i++) {
                    Carta row = lista.get(i);

                    Element elemento = new Element("carta");

                    elemento.setAttribute("id",                     String.valueOf(row.getId                        ()));
                    // Atributos del modelo 
                    elemento.setAttribute("modelo_carta_id",        String.valueOf(row.getMCarta().getId            ()));
                    // 501 - Permanente, 502 - Activada, 503 - Manager 
                    elemento.setAttribute("modelo_categoria_id",    String.valueOf(row.getMCarta().getCategoriaId   ()));

                    // Atributos de la carta 
                    elemento.setAttribute("categoria_id",   String.valueOf(row.getCategoriaId   ()));
                    elemento.setAttribute("duracion",       String.valueOf(row.getDuracion      ()));
                    elemento.setAttribute("rareza",         String.valueOf(row.getRareza        ()));
                    elemento.setAttribute("resumen",        String.valueOf(row.getResumen       ()));
                    elemento.setAttribute("cuartos",        String.valueOf(row.getCuartos       ()));

                    // Atributos comunes de la tienda 
                    elemento.setAttribute("estado",         String.valueOf(row.getEstado        ()));
                    elemento.setAttribute("precio",         String.valueOf(row.getPrecio        ()));
                    elemento.setAttribute("puntos",         String.valueOf(row.getPuntos        ()));
                    elemento.setAttribute("nivel",          String.valueOf(row.getNivel         ()));
                    elemento.setAttribute("eti",            String.valueOf(row.getEtiqueta      ()));

                    elemento.setAttribute("efecto_tipo",    String.valueOf(row.getEfectoTipo    ()));
                    elemento.setAttribute("efecto_valor",   String.valueOf(row.getEfectoValor   ()));
                    root.addContent(elemento);
                }
            }

            doc=new Document(root);//Creamos el documento
            doc.setDocType(null);
            out=new XMLOutputter();
        } catch (Exception e) {
            try { em.getTransaction().rollback(); } catch (Exception e2) { }
            log.error("[consultarCartas]: " , e);
//            pintarStackTrace(e.getStackTrace());

        } finally {
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }

        return out.outputString(doc);
    }

    public String consultarCartasServidor ( HttpServletRequest request, HttpServletResponse response) {
        EntityManager   em          = null;
        XMLOutputter    out         = null;
        Document        doc         = null;
        int             error       = 0;
        short           id          = 0;

log.debug("[consultarCartas Inicio]: " );

        try {
            em = emfTienda.createEntityManager(); // check 07.08.2012

            // componemos el xml 
            Element root=new Element("consultarCartas");
            root.setAttribute("err", new Integer(error).toString());

            Query q = em.createNamedQuery("Carta.findServidor");
            List<Carta> lista = q.getResultList();

            if (!lista.isEmpty()) {
                for ( int i=0;i< lista.size(); i++) {
                    Carta row = lista.get(i);

                    Element elemento = new Element("c");

                    elemento.setAttribute("id",         String.valueOf(row.getId                        ()));
                    // Atributos del modelo 
                    elemento.setAttribute("mod",        String.valueOf(row.getMCarta().getId            ()));
                    // 501 - Permanente, 502 - Activada, 503 - Manager 
                    elemento.setAttribute("m_cat",   String.valueOf(row.getMCarta().getCategoriaId   ()));

                    // Atributos de la carta 
                    elemento.setAttribute("cat",     String.valueOf(row.getCategoriaId   ()));
                    elemento.setAttribute("dur",        String.valueOf(row.getDuracion      ()));
                    elemento.setAttribute("qts",        String.valueOf(row.getCuartos       ()));
                    elemento.setAttribute("fx",         String.valueOf(row.getEfectoTipo    ()));
                    elemento.setAttribute("fxv",        String.valueOf(row.getEfectoValor   ()));
                    root.addContent(elemento);
                }
            }

            doc=new Document(root);//Creamos el documento
            doc.setDocType(null);
            out=new XMLOutputter();
        } catch (Exception e) {
            try { em.getTransaction().rollback(); } catch (Exception e2) { }
            log.error("[consultarCartas]: " , e);
        } finally {
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }

        return out.outputString(doc);
    }


    // Consulta toda la ropa de la tienda ordenada por marca y coleccion 
    public String consultarTiendaRopa ( HttpServletRequest request, HttpServletResponse response) {
log.debug("[TRAZA][Entro en consultarTiendaRopa]");
        EntityManager   em          = null;
        XMLOutputter    out         = null;
        Document        doc         = null;
        int             error       = 0;

        try {
            log.debug("[TRAZA][Creo el entity Manager]");
            em = emfTienda.createEntityManager(); // check 07.08.2012

            // componemos el xml 
            Element root=new Element("consultarTienda");
            root.setAttribute("err", new Integer(error).toString());

            Query q = em.createNamedQuery("Ropa.findActivasyOcultas");
            List<Ropa> lista = q.getResultList();

            if (!lista.isEmpty()) {
                for ( int i=0;i< lista.size(); i++) {
                    Ropa row = lista.get(i);

                    Element elemento=new Element("ropa");

                    elemento.setAttribute("id",                 String.valueOf(row.getId                    ()));
                    elemento.setAttribute("estado",             String.valueOf(row.getEstado                ()));
                    elemento.setAttribute("nombre",             String.valueOf(row.getNombre                ()));
                    elemento.setAttribute("mar_id",             String.valueOf(row.getMarca().getId         ()));
                    elemento.setAttribute("cat_id",             String.valueOf(row.getCategoria().getId     ()));
                    elemento.setAttribute("nom_categoria",      String.valueOf(row.getCategoria().getNombre ()));
                    elemento.setAttribute("coleccion_id",       String.valueOf(row.getColeccion().getId     ()));
                    elemento.setAttribute("modelo",             String.valueOf(row.getModelo                ()));
                    elemento.setAttribute("textura",            String.valueOf(row.getTextura               ()));

                    elemento.setAttribute("precio",             String.valueOf(row.getPrecio    ()));
                    elemento.setAttribute("puntos",             String.valueOf(row.getPuntos    ()));
                    elemento.setAttribute("nivel",              String.valueOf(row.getNivel     ()));
                    elemento.setAttribute("eti",                String.valueOf(row.getEtiqueta      ()));

                    elemento.setAttribute("prop1",              String.valueOf(row.getProp1     ()));
                    elemento.setAttribute("valor1",             String.valueOf(row.getValor1    ()));
                    elemento.setAttribute("modif1",             String.valueOf(row.getModif1    ()));

                    elemento.setAttribute("prop2",              String.valueOf(row.getProp2     ()));
                    elemento.setAttribute("valor2",             String.valueOf(row.getValor2    ()));
                    elemento.setAttribute("modif2",             String.valueOf(row.getModif2    ()));

                    elemento.setAttribute("prop3",              String.valueOf(row.getProp3     ()));
                    elemento.setAttribute("valor3",             String.valueOf(row.getValor3    ()));
                    elemento.setAttribute("modif3",             String.valueOf(row.getModif3    ()));

                    elemento.setAttribute("prop4",              String.valueOf(row.getProp4     ()));
                    elemento.setAttribute("valor4",             String.valueOf(row.getValor4    ()));
                    elemento.setAttribute("modif4",             String.valueOf(row.getModif4    ()));

                    elemento.setAttribute("usos",               String.valueOf(row.getUsos      ()));
                    elemento.setAttribute("dias",               String.valueOf(row.getDias      ()));
                    
                    root.addContent(elemento);
                }
            }
            doc=new Document(root);//Creamos el documento
            doc.setDocType(null);

            out=new XMLOutputter();
        } catch (Exception e) {
            try { em.getTransaction().rollback(); } catch (Exception e2) { }
            log.error("[consultarRopa]: " , e);
        } finally {
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }

        return out.outputString(doc);
    }

    public String consultarSaldoEquipo ( HttpServletRequest request, HttpServletResponse response) {

        EntityManager   em          = null;
        XMLOutputter    out         = null;
        Document        doc         = null;
        int             error       = 0;
        int             equipo_id  = -1;

        log.debug("[TRAZA][Entro en consultarTiendaRopa. OJO este WS tendría que ser privado]");

        try {
            log.debug("[TRAZA][Creo el entity Manager]");

            em = emfTienda.createEntityManager(); // check 07.08.2012

            // componemos el xml 
            Element root=new Element("consultarSaldoEquipo");
            root.setAttribute("err", new Integer(error).toString());

            Query  q = null;

            if ( request.getParameter("equipo_id") != null ) {
                equipo_id = Integer.parseInt(request.getParameter("equipo_id"));
                q = em.createNamedQuery("Equipo.findById");
                q.setParameter("idEquipo", equipo_id);
            } else {
                throw new ExcepcionGeneral( -3, "Falta el parametro equipo_id" );
            }

            // Comprobacion de Sesión 
            HttpSession miSesion = request.getSession(true);
            String idSesion = miSesion.getId();
            log.debug("[SESION]"+miSesion.getId());

            if (idSesion != null && equipo_id != 0 ) {
                LoginAction la = new LoginAction();
                int aux_usuario_id = la.comprobarSesionEquipo( idSesion, equipo_id, em );
                if ( aux_usuario_id <0 ) {
                    throw new ExcepcionGeneral( -4, "Sesión Incorrecta" );
                }
            }

            List<Equipo> lista = q.getResultList();
            if (!lista.isEmpty()) {
                for ( int i=0;i< lista.size(); i++) {
                    Equipo row = lista.get(i);

                    Element el_equipo=new Element("equipo");

                    el_equipo.setAttribute("equipo_id",          String.valueOf(row.getId            ()));
                    el_equipo.setAttribute("equipo_nombre",      String.valueOf(row.getNombre        ()));
                    el_equipo.setAttribute("equipo_nick",        String.valueOf(row.getNick          ()));
                    el_equipo.setAttribute("puntos",             String.valueOf(row.getPuntos        ()));
                    el_equipo.setAttribute("nivel",              String.valueOf(row.getNivel         ()));

                    el_equipo.setAttribute("usuario_id",         String.valueOf(row.getUsuario().getId       ()));
                    el_equipo.setAttribute("usuario_nick",       String.valueOf(row.getUsuario().getNick     ()));
                    el_equipo.setAttribute("usuario_creditos",   String.valueOf(row.getUsuario().getCreditos ()));

                    root.addContent(el_equipo);
                }
            }

            doc = new Document(root);//Creamos el documento
            doc.setDocType(null);
            out = new XMLOutputter();
        } catch (Exception e) {
            try { em.getTransaction().rollback(); } catch (Exception e2) { }
            log.error("[consultarRopa]: " , e);
        } finally {
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }

        return out.outputString(doc);
    }

    public String consultarTalentos ( HttpServletRequest request, HttpServletResponse response) {
        EntityManager   em          = null;
        XMLOutputter    out         = null;
        Document        doc         = null;
        int             error       = 0;
        short           id          = 0;

log.debug("[consultarTalentos Inicio]: " );

        try {
            em = emfTienda.createEntityManager(); // check 07.08.2012

            // componemos el xml
            Element root=new Element("consultarTalentos");
            root.setAttribute("err", new Integer(error).toString());

            Query q = em.createNamedQuery("Talento.findByTienda");
            List<Talento> lista = q.getResultList();

            if (!lista.isEmpty()) {
                for ( int i=0;i< lista.size(); i++) {
                    Talento row = lista.get(i);

                    Element elemento = new Element("talento");

                    elemento.setAttribute("id",             String.valueOf(row.getId                        ()));
                    elemento.setAttribute("nombre",         String.valueOf(row.getNombre()));
                    elemento.setAttribute("categoria_id",   String.valueOf(row.getCategoriaId   ()));
                    elemento.setAttribute("nivel",          String.valueOf(row.getNivel()));
                    elemento.setAttribute("nivel_equipo",   String.valueOf(row.getNivelEquipo()));
                    elemento.setAttribute("coste",          String.valueOf(row.getCoste()));
                    elemento.setAttribute("tipo",           String.valueOf(row.getTipo()));
                    elemento.setAttribute("recarga",        String.valueOf(row.getRecarga()));
                    elemento.setAttribute("duracion",       String.valueOf(row.getDuracion()));
                    elemento.setAttribute("efecto_tipo",    String.valueOf(row.getEfectoTipo()));
                    elemento.setAttribute("efecto_valor",   String.valueOf(row.getEfectoValor()));
                    root.addContent(elemento);
                }
            }

            doc=new Document(root);//Creamos el documento
            doc.setDocType(null);
            out=new XMLOutputter();
        } catch (Exception e) {
            try { em.getTransaction().rollback(); } catch (Exception e2) { }
            log.error("[consultarTalentos]: " , e);
        } finally {
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }

        return out.outputString(doc);
    }

        public String consultarModeloTalento ( HttpServletRequest request, HttpServletResponse response) {
        EntityManager   em          = null;
        XMLOutputter    out         = null;
        Document        doc         = null;
        int             error       = 0;
        short           id          = 0;

log.debug("[consultarModeloTalento Inicio]: " );

        try {
            em = emfTienda.createEntityManager(); // check 07.08.2012

            // componemos el xml 
            Element root=new Element("consultarModeloTalento");
            root.setAttribute("err", new Integer(error).toString());

            Query q = em.createNamedQuery("CategoriaTalentoModeloJugador.findAll");
            List<CategoriaTalentoModeloJugador> lista = q.getResultList();

            int ant_modelo_id=-1;
            Element elemento_modelo = null;
            if (!lista.isEmpty()) {
                for ( int i=0;i< lista.size(); i++) {
                    CategoriaTalentoModeloJugador row = lista.get(i);

                    if ( row.getCategoriaTalentoModeloJugadorPK().getModeloId() != ant_modelo_id ) {
                        elemento_modelo= new Element("modelo");
                        elemento_modelo.setAttribute("id", String.valueOf(row.getCategoriaTalentoModeloJugadorPK().getModeloId()));
                        //if ( ant_modelo_id != -1)
                        root.addContent(elemento_modelo);
                        ant_modelo_id = row.getCategoriaTalentoModeloJugadorPK().getModeloId();
                    }

                    Element hijo = new Element("categoria");
                    hijo.setAttribute("id", String.valueOf(row.getCategoriaTalentoModeloJugadorPK().getCatTalento()));
                    elemento_modelo.addContent(hijo);
                }
            }

            doc=new Document(root);//Creamos el documento
            doc.setDocType(null);
            out=new XMLOutputter();
        } catch (Exception e) {
            try { em.getTransaction().rollback(); } catch (Exception e2) { }
            log.error("[consultarTalentos]: " , e);
        } finally {
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }

        return out.outputString(doc);
    }

    public String consultarEscuelas ( HttpServletRequest request, HttpServletResponse response) {
    // Consulta para el servidor de juego donde devolvemos el identificador de cada escuela y el
    // identificador de cada modelo de jugador al que pertenece

        EntityManager   em          = null;
        XMLOutputter    out         = null;
        Document        doc         = null;
        int             error       = 0;
        short           id          = 0;

log.debug("[consultarEscuelas Inicio]: " );

        try {
            em = emfTienda.createEntityManager(); // check 07.08.2012

            // componemos el xml 
            Element root=new Element("consultarEscuelas");
            root.setAttribute("err", new Integer(error).toString());

            Query q = em.createNamedQuery("MJugador.findAll");
            List<MJugador> lista = q.getResultList();

            if (!lista.isEmpty()) {
                for ( int i=0;i< lista.size(); i++) {
                    MJugador row = lista.get(i);

                    Element elemento = new Element("m_jugador");

                    elemento.setAttribute("id",             String.valueOf(row.getId    ()));
                    elemento.setAttribute("escuela_id",     String.valueOf(row.getEscuela().getId()));
                    root.addContent(elemento);
                }
            }

            doc=new Document(root);//Creamos el documento
            doc.setDocType(null);
            out=new XMLOutputter();
        } catch (Exception e) {
            try { em.getTransaction().rollback(); } catch (Exception e2) { }
            log.error("[consultarTalentos]: " , e);
        } finally {
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }

        return out.outputString(doc);
    }

    public String consultarRopas ( HttpServletRequest request, HttpServletResponse response) {
    // Consulta para el servidor de juego donde devolvemos el identificador de cada ropa y el campo cuando

        EntityManager   em          = null;
        XMLOutputter    out         = null;
        Document        doc         = null;
        int             error       = 0;
        short           id          = 0;

log.debug("[consultarRopas Inicio]: " );

        try {
            em = emfTienda.createEntityManager(); // check 07.08.2012

            // componemos el xml 
            Element root=new Element("consultarRopas");
            root.setAttribute("err", new Integer(error).toString());

            Query q = em.createNamedQuery("Ropa.findAll");
            List<Ropa> lista = q.getResultList();

            if (!lista.isEmpty()) {
                for ( int i=0;i< lista.size(); i++) {
                    Ropa row = lista.get(i);

                    Element elemento = new Element("ropa");

                    elemento.setAttribute("id",         String.valueOf(row.getId    ()));
                    elemento.setAttribute("cuando",     String.valueOf(row.getCuando()));
                    root.addContent(elemento);
                }
            }

            doc=new Document(root);//Creamos el documento
            doc.setDocType(null);
            out=new XMLOutputter();
        } catch (Exception e) {
            try { em.getTransaction().rollback(); } catch (Exception e2) { }
            log.error("[consultarRopas]: " , e);
        } finally {
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }

        return out.outputString(doc);
    }

    public String traducciones ( HttpServletRequest request, HttpServletResponse response) {
    // Consulta para que los clientes tengan todos los items de la base de datos
    // con su traducción de trabajo, que luego será localizada al resto de idiomas
    //
        EntityManager   em          = null;
        int             error       = 0;
        short           id          = 0;
        String          salida      = null;
        Query           q           = null;

        log.debug("[traducciones Inicio 2]: " );

        try {
            em = emfTienda.createEntityManager(); // check 07.08.2012

            // componemos la salida

            salida= "1|2000|Tatuaje\n" +
                    "1|2001|Zapatilla\n" +
                    "1|2002|Muñequera\n" +
                    "1|2003|Brazalete\n";

            // ROPAS
            //Query q = em.createNamedQuery("Ropa.findAll");
            q = em.createQuery("SELECT x FROM Ropa x order by x.id");
            List<Ropa> lista = q.getResultList();
            if (!lista.isEmpty()) {
                for ( int i=0;i< lista.size(); i++) {
                    Ropa row = lista.get(i);

                    salida+= "11|";
                    salida+= String.valueOf(row.getId    ()) + "|";
                    salida+= String.valueOf(row.getNombre()) + "\n";
                }
                for ( int i=0;i< lista.size(); i++) {
                    Ropa row = lista.get(i);

                    salida+= "12|";
                    salida+= String.valueOf(row.getId    ()) + "|";
                    salida+= String.valueOf(row.getDescripcion()) + "\n";
                }
            }

            // MODELOS DE CARTAS
            // q = em.createNamedQuery("MCarta.findAll");
            q = em.createQuery("SELECT x FROM MCarta x order by x.id");
            List<MCarta> lista_m_carta = q.getResultList();
            if (!lista_m_carta.isEmpty()) {
                for ( int i=0;i< lista_m_carta.size(); i++) {
                    MCarta row = lista_m_carta.get(i);

                    salida+= "22|";
                    salida+= String.valueOf(row.getId    ()) + "|";
                    salida+= String.valueOf(row.getNombre()) + "\n";
                }
            }

            // CARTAS
            // q = em.createNamedQuery("Carta.findAll");
            q = em.createQuery("SELECT x FROM Carta x order by x.id");
            List<Carta> lista_carta = q.getResultList();
            if (!lista_carta.isEmpty()) {
                for ( int i=0;i< lista_carta.size(); i++) {
                    Carta row = lista_carta.get(i);

                    salida+= "23|";
                    salida+= String.valueOf(row.getId    ()) + "|";
                    salida+= String.valueOf(row.getDescripcion()) + "\n";
                }
                for ( int i=0;i< lista_carta.size(); i++) {
                    Carta row = lista_carta.get(i);
                    if ( row.getNombre() != null ){
                        salida+= "24|";
                        salida+= String.valueOf(row.getId    ()) + "|";
                        salida+= String.valueOf(row.getNombre()) + "\n";
                    }
                }
            }

            // SOBRE
            // q = em.createNamedQuery("Sobre.findAll");
            q = em.createQuery("SELECT x FROM Sobre x order by x.id");
            List<Sobre> lista_sobre = q.getResultList();
            if (!lista_sobre.isEmpty()) {
                for ( int i=0;i< lista_sobre.size(); i++) {
                    Sobre row = lista_sobre.get(i);

                    salida+= "25|";
                    salida+= String.valueOf(row.getId    ()) + "|";
                    salida+= String.valueOf(row.getNombre()) + "\n";
                }
            }
            {
                // UNIFORMES
                q = em.createQuery("SELECT x FROM Objeto x where x.tipo=11 order by x.id");
                List<Objeto> lista_objeto = q.getResultList();
                if (!lista_objeto.isEmpty()) {
                    for ( int i=0;i< lista_objeto.size(); i++) {
                        Objeto row = lista_objeto.get(i);

                        salida+= "29|";
                        salida+= String.valueOf(row.getId    ()) + "|";
                        salida+= String.valueOf(row.getNombre()) + "\n";
                    }
                }
                // BALONES
                q = em.createQuery("SELECT x FROM Objeto x where x.tipo=12 order by x.id");
                lista_objeto = q.getResultList();
                if (!lista_objeto.isEmpty()) {
                    for ( int i=0;i< lista_objeto.size(); i++) {
                        Objeto row = lista_objeto.get(i);

                        salida+= "28|";
                        salida+= String.valueOf(row.getId    ()) + "|";
                        salida+= String.valueOf(row.getNombre()) + "\n";
                    }
                }

            }

            //q = em.createNamedQuery("CartaObjeto.findAll");
            q = em.createQuery("SELECT x FROM Gashaball x order by x.id");
            List<Gashaball> lista_gashaball = q.getResultList();
            if (!lista_gashaball.isEmpty()) {
                for ( int i=0;i< lista_gashaball.size(); i++) {
                    Gashaball row = lista_gashaball.get(i);

                    salida+= "27|";
                    salida+= String.valueOf(row.getId         ()) + "|";
                    salida+= String.valueOf(row.getNombre     ()) +  "\n";
                }
            }


            // MODELOS DE JUGADOR
            //q = em.createNamedQuery("MJugador.findAll");
            q = em.createQuery("SELECT x FROM MJugador x order by x.id");
            List<MJugador> lis_m_jugador = q.getResultList();
            if (!lis_m_jugador.isEmpty()) {
                for ( int i=0;i< lis_m_jugador.size(); i++) {
                    MJugador row = lis_m_jugador.get(i);
                    salida+= "31|";
                    salida+= String.valueOf(row.getId    ()) + "|";
                    salida+= String.valueOf(row.getDescripcion()) + "\n";
                }
            }

            // TALENTO
            q = em.createQuery("SELECT x FROM Talento x order by x.id");
            List<Talento> lis_talento = q.getResultList();
            if (!lis_talento.isEmpty()) {
                for ( int i=0;i< lis_talento.size(); i++) {
                    Talento row = lis_talento.get(i);

                    salida+= "32|";
                    salida+= String.valueOf(row.getId    ()) + "|";
                    salida+= String.valueOf(row.getNombre()) + "\n";
                }
                for ( int i=0;i< lis_talento.size(); i++) {
                    Talento row = lis_talento.get(i);

                    salida+= "33|";
                    salida+= String.valueOf(row.getId    ()) + "|";
                    salida+= String.valueOf(row.getDescripcion()) + "\n";
                }
            }

salida+="41|1|Este equipo se caracteriza por jugar con una fórmula 'freestyle', basándose menos en el juego de equipo y más en su potencia como jugadores individuales dando unos resultados excelentes a la hora de establecer una alta puntuación.\n";
salida+="41|2|Este equipo destaca por su rapidez y astucia, bombardeando a sus oponentes con elevadas habilidades tanto ofensivas como defensivas. Todos sus jugadores son intrépidos y sorprendentes como zorros.\n";
salida+="41|3|Los jugadores de este equipo son brillantes estrategas que saben explotar al máximo sus habilidades. Aunque están en la media en su mayoría de las características su excelente juego en equipo les hace brillar como auténticas estrellas sobre el terreno de juego.\n";
salida+="41|4|La fortaleza principal de este equipo es la defensa; su gran habilidad para detener a los jugadores enemigos provoca la desesperación en sus adversarios, reaccionando al momento con fuertes contraataques que aseguran la victoria.\n";

        } catch (Exception e) {
            log.error("[traducciones]: " , e);
        } finally {
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }
        return salida;
    }
*/
    public int regalaDuddies ( EntityManager em, int equipo_id, int cantidad ) throws ExcepcionGeneral {
        String  retText;
        int     nuevo_credito = -1;

        Query q = em.createNamedQuery("Equipo.findById");
        q.setParameter("idEquipo", equipo_id);
        List<Equipo> lista_equipo = q.getResultList();

        if (lista_equipo.isEmpty() ) {
            // The equipo don't exists
            throw new ExcepcionGeneral( -12, "Team doesn't exists." );
        } else {
            if ( cantidad <0 && lista_equipo.get(0).getPuntos()<Math.abs(cantidad)  ) {
                throw new ExcepcionGeneral( -5, "Duddies must be lower than current amount." );
            } else {
                log.debug("Regalar duddies: " + equipo_id + " | " + cantidad);
                nuevo_credito = lista_equipo.get(0).getPuntos()+cantidad;
                lista_equipo.get(0).setPuntos( nuevo_credito  );

                return nuevo_credito;
            }
        }
    }

    public void wsConsultarSaldo (HttpServletRequest request, HttpServletResponse response ) {

        PrintWriter out = null;
        int retCode = 0;
        String retText = "";
        float bitoons = 0;

        EntityManager em = null;
log.debug("Consultar Saldo ");
        try {
            em = emfTienda.createEntityManager(); // check 07.08.2012

            HttpSession miSesion = request.getSession(true);
            String idSesion = miSesion.getId();

            LoginAction la = new LoginAction();
            int usuario_id = la.comprobarSesion(idSesion, em);
            if ( usuario_id < 0 ) {
                retCode = -3;
                retText = "Sesión Incorrecta";
            }

            Query q = em.createNamedQuery("Usuario.findById");
            q.setParameter("id", usuario_id );
            List<Usuario> existsUser = q.getResultList();
            if (existsUser.isEmpty()) {
log.error("No existe user_id: " + usuario_id);
                // The user doesn't exist
                retCode = -1;
                retText = "Nick doesn't exist";
            } else {
                Usuario usuario = existsUser.get(0);

                bitoons = usuario.getCreditos();

                retCode = 0;
                retText = "Successfull operation.";
            }
        } catch (Exception e) {
            log.error("Error: " , e);
            retCode = -3;
            retText = "General error";
        } finally {
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }

        // Pintar la salida
        try {
            out = response.getWriter();
            if ( retCode == 0 ) {
                out.print("error="+retCode+";bitoons="+bitoons);
            } else {
                out.print("error="+retCode+";descripcion="+retText);
            }
        } catch (Exception e) {
            log.error("Error trying to print the output: ", e);
        }
    }
}
